Virtual Serial Port for Linux

Solution 1:

Complementing the @slonik's answer.

You can test socat to create Virtual Serial Port doing the following procedure (tested on Ubuntu 12.04):

Open a terminal (let's call it Terminal 0) and execute it:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

The code above returns:

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]

Open another terminal and write (Terminal 1):

cat < /dev/pts/2

this command's port name can be changed according to the pc. it's depends on the previous output.

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs 

you should use the number available on highlighted area.

Open another terminal and write (Terminal 2):

echo "Test" > /dev/pts/3

Now back to Terminal 1 and you'll see the string "Test".

Solution 2:

You can use a pty ("pseudo-teletype", where a serial port is a "real teletype") for this. From one end, open /dev/ptyp5, and then attach your program to /dev/ttyp5; ttyp5 will act just like a serial port, but will send/receive everything it does via /dev/ptyp5.

If you really need it to talk to a file called /dev/ttys2, then simply move your old /dev/ttys2 out of the way and make a symlink from ptyp5 to ttys2.

Of course you can use some number other than ptyp5. Perhaps pick one with a high number to avoid duplicates, since all your login terminals will also be using ptys.

Wikipedia has more about ptys: http://en.wikipedia.org/wiki/Pseudo_terminal

Solution 3:

Use socat for this:

For example:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

Solution 4:

There is also tty0tty http://sourceforge.net/projects/tty0tty/ which is a real null modem emulator for linux.

It is a simple kernel module - a small source file. I don't know why it only got thumbs down on sourceforge, but it works well for me. The best thing about it is that is also emulates the hardware pins (RTC/CTS DSR/DTR). It even implements TIOCMGET/TIOCMSET and TIOCMIWAIT iotcl commands!

On a recent kernel you may get compilation errors. This is easy to fix. Just insert a few lines at the top of the module/tty0tty.c source (after the includes):

#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif

When the module is loaded, it creates 4 pairs of serial ports. The devices are /dev/tnt0 to /dev/tnt7 where tnt0 is connected to tnt1, tnt2 is connected to tnt3, etc. You may need to fix the file permissions to be able to use the devices.

edit:

I guess I was a little quick with my enthusiasm. While the driver looks promising, it seems unstable. I don't know for sure but I think it crashed a machine in the office I was working on from home. I can't check until I'm back in the office on monday.

The second thing is that TIOCMIWAIT does not work. The code seems to be copied from some "tiny tty" example code. The handling of TIOCMIWAIT seems in place, but it never wakes up because the corresponding call to wake_up_interruptible() is missing.

edit:

The crash in the office really was the driver's fault. There was an initialization missing, and the completely untested TIOCMIWAIT code caused a crash of the machine.

I spent yesterday and today rewriting the driver. There were a lot of issues, but now it works well for me. There's still code missing for hardware flow control managed by the driver, but I don't need it because I'll be managing the pins myself using TIOCMGET/TIOCMSET/TIOCMIWAIT from user mode code.

If anyone is interested in my version of the code, send me a message and I'll send it to you.