What are the implications of setting the baud rate of a terminal from userspace

devicessttyuartusb

Sometimes I just need to read from a serial device, so I skip the complexities of minicom or screen and just cat. However, this only works if I first set the baud rate of the terminal using stty <baud> before attempting to open the file.

This data is likely already (or can be) buffered in the kernel and, in this case, was received using a UART to USB bridge. USB transfer rates are fixed for a given standard, so setting the baud rate can only affect the interpretation of the data. Given my lack of insight into what this data might look like wrapped in USB packets, I am unsure how to visualize the "interpretation" of USB packet data at some fixed read rate (baud rate).

$ stty 115200
$ cat /dev/ttyACM0

What is really going on here? I understand the implications of this setting in hardware, but what does it mean in userspace software?

Best Answer

It looks like you might be a bit confused about how this all works.

First, /dev/ttyACM0 does not represent the USB link, or even the USB endpoint for whatever serial adapter you have connected, it represents the UART inside the adapter that handles the serial communications. Data you read from it will not include any USB headers or framing, just like data you read from /dev/ttyS0 will not include any PCI Express headers or framing. Setting the baud rate on these affects the hardware that it represents, not the bus it's connected to, so this won't do anything to the USB connection.

Second, the baud rate is a hardware setting, not a software one. When you call stty to set it on a serial port, that is telling the kernel to tell the hardware to change what baud rate it is trying to receive data at. This means in particular that any data that was received prior to this change will either be bogus (because it wasn't interpreted correctly by the hardware, sometimes the case if the baud rates are close to each other or exact harmonics), or completely lost (because the hardware just didn't accept it, the more likely case on modern hardware).

If you plan on reading data from a serial line, you need to have the baud rate set correctly prior to any data being transmitted by the other end. This also means that changing the baud rate won't change how the kernel interprets the data. If the data is already buffered in the kernel, then it's not going to change just because you change the baud rate (although it is good practice after changing the baud rate to drain the kernel buffers so that you know any future data is good).

So, to clarify, the correct method to get data out of a USB to serial adapter without using special software is to:

  1. Set the baud rate during system startup. For a USB to serial adapter, this should probably be a udev rule so that it gets set when the device gets plugged in too.
  2. Use cat (or od if you need the byte values instead of text) to read data. This will return the exact data that is received by the USB to serial adapter (assuing the adapter doesn't do special processing).
Related Question