views:

875

answers:

4

I have a program, using pyserial, and I want to test it without using a real serial port device.

In windows, I use com0com, and in linux, I know there is a method to create virtual serial port pair without using additional program.

so I look up the manual, and found pts, /dev/ptmx, but I don't know how to create a pair by following the manual, can anyone give me a example?

I tried(in python):

f = open("/dev/ptmx", "r")

and it works, /dev/pts/4 is created.

and I tried:

f = open("/dev/4", "w")

and the result is:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 5] Input/output error: '/dev/pts/4'

edit: I found a solution(workround), using socat.

socat PTY,link=COM8 PTY,link=COM9

then COM8 COM9 are created as virtual serial port pair.

A: 

Per the docs, you need ptsname to get the name of the slave-side of the pseudo-terminal, and also, quoting the docs,

Before opening the pseudo-terminal slave, you must pass the master's file descriptor to grantpt(3) and unlockpt(3).

You should be able to use ctypes to call all of the needed functions.

Alex Martelli
are there any example? C/python/C++?
linjunhalida
I found a long C example, http://www.developerweb.net/forum/showthread.php?t=5623 , but no Python examples.
Alex Martelli
Python examples are hidden in the `pty` module, although it conveniently lets `os.openpty` do the actual work when it can :)
Thomas Wouters
Tx @Thomas! Off to study pty sources again...
Alex Martelli
openpty is great, and I can use it for IPC, but not fit for testing another program using serial port...
linjunhalida
If openpty isn't fit, then I don't see how you expect to use the (exact same) terminal you get from managing /dev/ptmx yourself.
Thomas Wouters
A: 

I don't know python but I can point you in the right direction: look here at a C code sample. Here's the man page for the /dev/ptmx. Make sure the permissions and owner is correct!. Here is the poster on the linuxquestions forum on how to use it from C.

Hope this helps, Best regards, Tom.

tommieb75
A: 

You should consider using the pty module instead, which should take care of this for you. (it opens /dev/ptmx or calls openpty or opens another appropriate device, depending on the platform.)

Thomas Wouters
A: 

You could build a dummy object that implements the same interface as the pySerial classes you use, but do something completely different and easily replicable like reading from and writing to files/terminal/etc.

For example:

class DummySerial():
  #you should consider subclassing this
  def __init__(self, *args, **kwargs):
    self.fIn = open("input.raw", 'r')
    self.fOut = open("output.raw", 'w')
    pass
  def read(self, bytes = 1):
    return self.fIn.read(bytes)
  def write(self, data):
    self.fOut.write(data)
  def close(self):
    self.fIn.close()
    self.fOut.close()
  #implement more methods here

If it quacks like a duck and it ducks like a duck...

badp
yet another solution...enlightening.
linjunhalida