Using Raspberry Pi as a serial server

With ser2net, one is able to utilize Raspberry Pi as a serial-to-tcp server, sharing the serial connection over the Internet. This is particularly useful when it comes to virtualization, where a virtual machine could connect to a serial device without the need to passthrough a set of USB controllers (I’m not even sure a COM port can be passed through).

Still, there are some caveats when using this method.

1) ser2net can only serve one connection to one port at a time, so there is no multi-threading on single COM port. This makes sense since COM ports are exclusive - you can’t have multiple simultaneous accesses to one COM port.

2) It needs some extra configuration, both on the server and client sides.

Setting up the connection itself on Raspberry Pi is fairly straightforward. Use the USB-to-serial connector you like (I used a PL2303-based convertor), plug it in and hopefully Linux can recognize it out-of-box, at least it is the case for me. A dmesg shows that pl2303 is attached to /dev/ttyUSB0:

[3.930235] usbcore: registered new interface driver pl2303
[3.930351] usbserial: USB Serial support registered for pl2303
[3.930441] pl2303 1-1.2:1.0: pl2303 converter detected
[3.939509] usb 1-1.2: pl2303 converter now attached to ttyUSB0

And here’s the first caveat. Somehow, udev does not create this device with the proper permissions, so you’ll need to add a rule for udev configuration, by creating a rule file, say /etc/udev/rules.d/10-pl2303.rules:

ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666"

If you’re not using pl2303 but something else, use lsusb to find the vendor and produid for the convertor, and fill them in here.

After reboot, use cu to test the connection of serial:

sudo cu -l /dev/ttyUSB0 -s 9600

And if that works, install ser2net and edit /etc/ser2net.conf, adding a line to the end of the file, and comment out existing entries if needed:

9999:raw:600:/dev/ttyUSB0:9600 8DATABITS NONE 1STOPBIT

The configuration parses fields separated by colons. First field is port, second mode, third timeout, fourth device name, fifth are options separated by spaces or commas, including baud rate, data bits, parity, XON/XOFF, hardware flow control and STOP bits. Additional information can be found in the configuration examples or https://linux.die.net/man/8/ser2net.

Now the server-end setup is completed. If the client is Linux, simply use nc raspberry.pi.ip.addr 9999 will open a connection to the serial port, or alternatively using socat will also work.

For Windows client, after some testing I found Perle TruePort driver works the best, but that is not out-of-box. You can download it from https://www.perle.com/downloads/trueport.shtml, and install the version you need. Once installed, add a new TruePort adapter, and fill in the IP/FQDN or Raspberry Pi, and select properties.

In the configuration tab, click Settings, and choose the COM port you have just created. The first thing of course, is to change the default port 10001 to whatever port you have defined in ser2net configuration. Then, change the connection mode from “Full Mode” to”Automatic”, and in Advanced tab, change the behavior of “On COM port open” from “Return when connection is fully established” to “Always return successful”.

Now you’re done! Use your favorite client to access the COM port, e.g., Putty.