1

Currently, I have a desktop app that I used to read and write data to a proprietary hardware device via a serial port interface. The app starts by listing the serial COM devices connected to the computer, and once a device is selected, one can interact with the app to communicate with the corresponding device. I no longer have such a device at hand, but I would still like to use the app nonetheless.

I have already developed a command-line utility that, given a binary message in stdin, emits the corresponding binary reply (the same reply that the proprietary hardware device would send via serial port) to stdout. Let's call this utility a simulator.

How do I set up a virtual serial port such that the app can detect it, and that whenever the app sends a message using the serial port protocol, such message is forwarded to the simulator, and the simulator's reply is returned back to the desktop app?

I'm on Mac OS 12 with an M1 CPU. I'm also open to solutions on Windows 10 (with less priority).

I have looked at previous questions on StackOverflow that might be similar to this one, but they were either incomplete or slightly different, with no obvious way to infer the solution for my actual problem.

Alberto Schiabel
  • 1,049
  • 10
  • 23
  • Most likely you would either have to write a driver (one of the new user space drivers) or use external hardware (such as two USB-to-serial adapters wired to each other or a custom USB-to-serial implementation). – Codo Jan 06 '22 at 22:17
  • This article may be helpful. [LINUX - ComPort over Network](https://gist.github.com/DraTeots/e0c669608466470baa6c#linux) – kunif Jan 06 '22 at 23:00
  • Have you tried to use `socat` ? – Richard Barber Jan 07 '22 at 02:54
  • Hi, I'm not familiar with writing drivers (nor in the user or kernel space) or with socat. Could you please expand more on these topics? Could you maybe provide a small but meaningful and working example? – Alberto Schiabel Jan 07 '22 at 09:10
  • @RichardBarber OP is looking for a solution to create a new serial port as the legacy application expects a serial port. I don't think that *socat* can do that. – Codo Jan 07 '22 at 16:08
  • @kunif OP is looking for a solution to create a new serial port as the legacy application expects a serial port. I don't think that any of the solutions you have linked (*ser2net*, * com0com*) can do that. – Codo Jan 07 '22 at 16:08
  • @Codo Socat will read/write data from a serial port on the command line. – Richard Barber Jan 07 '22 at 16:12
  • @Codo , Apple forms a closed world, so it may not be possible with MacOS. But as I mentioned, the solution seems to work for Linux and Windows. – kunif Jan 07 '22 at 16:38

2 Answers2

2

Serial ports are unlike other channels. That's why separate system calls exist for them.

Normally, serial ports are created by physical devices (an old-fashioned serial port or a newer USB-based one) and the associated driver. Since writing a driver is quite difficult, a pragmatic and possibly unexpected approach would be to use hardware, specifically two USB-to-serial adapters. That way, a serial port is created by the drivers of the USB-to-serial adapter.

hardware setup

The two USB-to-serial adapters are wired to each other (RX to TX and vice versa). The will appear as two serial ports on macOS (/dev/cu.usb...).

The legacy application then connects to one of the serial ports. And your command line utility (acting as a device emulation) connects to the other serial port. All data send by the command line utility will go to the legacy application, and vice versa.

The remaining issue is how to connect your command line utility to the serial port. If you are lucky, you can use the screen command. But more likely, you will need to modify it to read and write from the serial port (instead of stdin and stdout).

Codo
  • 75,595
  • 17
  • 168
  • 206
  • Thank you for this answer. I think I'd rather go the driver path, rather than having to carry around two USB-to-serial adapters (plus the adapters from USB-C to USB-A). Would you have any resources about that? – Alberto Schiabel Jan 08 '22 at 21:18
  • No, I'm not familiar with writing device drivers. And there is hardly any documentation from Apple about it. – Codo Jan 09 '22 at 08:20
0

Creating a virtual serial port on Mac OS 13 with an apple silicon M1 CPU.

Open a terminal and execute it:

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

The code above returns something like:

2023/08/18 23:12:40 socat[98468] N PTY is /dev/ttys002
2023/08/18 23:12:40 socat[98468] N PTY is /dev/ttys003
2023/08/18 23:12:40 socat[98468] N starting data transfer loop with FDs 
[5,5] and [7,7]

In essence, it creates two virtual serial ports and connect them, enabling bidirectional communication between them (/dev/ttys002 and /dev/ttys003). For example, I used this command to allow an Arduino simulator to communicate via serial port with a Processing app.

*All credits to https://stackoverflow.com/a/19733677/953287

rafaello
  • 2,385
  • 1
  • 18
  • 16