Virtual Serial Ports Using Socat

How can you test and debug programs using serial port communication when you don’t have access to a physical serial port? Using the socat utility to create virtual serial ports which pipe port traffic to custom executables using stdin/stdout.

Here is the magic command you need:

socat -d -d -v pty,rawer,link=<PORT_NAME> EXEC:<COMMAND>,pty,rawer

It took me a while to find the correct combination of options to make this work. Here’s what I’ve used…

The first pty options creates the virtual serial port. It turns out terminal echo using rawer. The port is created using the file id given by the link option. The EXEC option will run the executable (given by the COMMAND value) and connect to the virtual serial port using stdin & stdout.

The -d -d -v options are used to print virtual port stream values to the console as well as the target.

Why would you want to do this?

Recently, I’ve been working on an embedded system which used a physical serial port for communication. Application commands and device responses were exchanged using the device’s serial port. As part of the development, there was a series of system tests which ran from the development machine, sending example commands to the device and then checking the responses against expected values.

As part of the testing process, I wanted to run the system tests in the CI/CD pipeline. This came with the challenge that the test environment would not have the device connected to the serial port. Thinking about how to handle this, I eventually settled on a neat solution using the socat utility.

Using the tool, I could create a virtual serial port in the test environment. This virtual serial port was configured to pipe all data transferred to an executable (using stdin and stdout). The embedded code was compiled into an executable for the test platform - using a custom runner script and a mock serial API which read from and wrote to stdin and stdout. The systems test just needed to use the virtual port name to run in the test environment without modification.

Being able to create virtual serial ports (which pipe data to stdin/stdout or custom executables) is a really useful feature for testing and debugging programs which use serial ports for communication!