UART latency on PC vs Microcontroller
So I wanted to do some faster embedded development by using my PC + a serial port instead of a microcontroller directly and things didn’t go as planned. Even though the absolute fastest speeds I would be dealing with were 38400bps my PC was struggling to keep up with the incoming data. So I plugged in the logic analyzer and checked what the issue was and…
OK, that was unexpected. The time between receiving a byte, processing it, and sending it back through the serial port was an insultingly slow 14ms. That’s enough time to send dozens of bytes! So a fix of some sort was needed, so I poked around the Internet for a while and discovered Linux has a “low latency” mode for these kind of peripherals, so I enabled it and the time improved a lot.
With a delay of 1565μs (roughly 10x faster) it was now well within acceptable margins, still quite slow but acceptable. So I decided to test if sacrificing the debugger by using a release build it would improve significantly. And the result became
1309μs barely worth the change. A good thing actually since I would have missed the debugger a lot.
Now, even though the ~1500μs delay between the input stop bit and the processed output start bit is acceptable, how does a 16 core, gigahertz computer compare against a meager 16 bit microcontroller running at 16 megahertz?
Well, the microcontroller is able to process and start sending the reply before the input byte itself is even finished transmitting. By the time the stop bit is sampled correctly near its midpoint, the microcontroller is already preparing the response and has it ready before the remaining half-bit is finished. Quite impressive how big of an overhead a PC has and how low it is on any simple 8 or 16 bit micro.
2022/03/30 Update: Windows users need not to feel left out. On windows the exact same problem exists, but there is apparently no easy solution like Linux’s “low latency” flag, however, a serial port can be configured system wide to have a similarly low latency as in linux. Just head to the device manager, go to the “Settings” tab on your preferred COM port, click “Advanced” and on that dialog, select the lowest latency you can.
There is a catch tho, it seems some vendors allow setting the latency low (FTDI) while others only allow you to set the receive buffer size or disable buffering altogether. While this should solve the latency issue, your mileage may vary.
Stop-to-Start bit delays
Environment | Delay |
---|---|
Default PC configuration | 14434 μs |
Linux “low-latency” mode | 1565 μs |
Linux “low latency” (no debugger) | 1309 μs |
PIC24 microcontroller | -5 μs |