Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active September 28, 2019 21:45
Show Gist options
  • Save CMCDragonkai/72f013a146030cc0d364ee1c230e0160 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/72f013a146030cc0d364ee1c230e0160 to your computer and use it in GitHub Desktop.
Virtual Serial Ports #cli #serial #network

Virtual Serial Ports

We can use socat to create 2 virtual serial ports that are connected to each other locally. This can be useful for debugging serial port applications. Or simulating serial port communication. Or running 2 legacy programs that only communicate with each other over serial ports, such as old DOS games. And of course, for education, since serial communication is probably the most simple communication protocol there is, RS232 is considered at the bottom of the OSI stack, at the "Physical Layer". See: http://electronics.stackexchange.com/questions/31171/internet-vs-serial-communication

> # create 2 pseudo ttys that are raw, and with echo disabled
> socat -d -d pty,raw,echo=0 pty,raw,echo=0 &

[1] 4952
2016/04/29 00:47:08 socat[548] N PTY is /dev/pty1
2016/04/29 00:47:08 socat[548] N PTY is /dev/pty3
2016/04/29 00:47:08 socat[548] N starting data transfer loop with FDs [5,5] and [7,7]

> stty --file=/dev/pty1

speed 38400 baud; line = 0;
min = 1; time = 0;
-brkint -icrnl -imaxbel
-opost
-isig -icanon -echo

> stty --file=/dev/pty3 -a 

speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

> # run picocom mapping \r to \r\n when writing to serial port, and enabling local echo so you can see what you type
> picocom --baud 38400 --omap crcrlf --echo /dev/pty1

picocom v2.2a

port is        : /dev/pty1
flowcontrol    : none
baudrate is    : 38400
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : yes
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        :
omap is        : crcrlf
emap is        : crcrlf,delbs,

Type [C-a] [C-h] to see available commands

Terminal ready

Now launch a second terminal:

> picocom --baud 38400 --omap crcrlf --echo /dev/pty3

Now you can type to each other!

For discussion of baud vs bits per second, see: http://www.tldp.org/HOWTO/Modem-HOWTO-23.html

This is actually a form of:

It appears that picocom sets its own settings on the terminal device, while saving the original settings to be restored once picocom exits. This does mean that if you run stty -F /dev/pty1 cs5, picocom will reset it by default to cs8, and once it exits, it will restore it back to cs5. There's not much point in setting these flags in stty then, as you will need to set them in picocom anyway. This behaviour can be changed with --noinit flag.

Note that input mapping in picocom refers to mapping bytes from reading the serial port. While output mapping means mapping from STDIN to serial port. Finally echo mapping means mapping characters from STDIN to STDOUT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment