Search code examples
serial-portembeddedreal-timemicrocontrollerhardware

On a microcontroller, is it possible to use polling to read the serial port without losing incoming data?


On a microcontroller, is it possible to use polling to read the serial port without losing incoming data?

Assume my MCU has a 1 byte HW buffer for the UART. At 115200 baud, that means I have about 70us to get an incoming byte before it's lost. Even at 9600 baud, I have less than a ms.

Achieving that latency is very hard. Moreover, on a RTOS, it runs a real risk of starving other threads (since e.g. FreeRTOS always runs a high priority task over a lower one).

Understood that polling is CPU expensive. But in cases where CPU is available, it's also simpler. But it seems its a non-starter to receive serial data if anything else is going on. Is that correct? If not, how can you poll on a serial port receive?


Solution

  • This is a very common scenario and there's a standard way to implement this. Polling would be senseless unless the program can be allowed to not do anything else for a long period of time.

    What is used instead is the UART RX interrupt. From the ISR you store the incoming data in a ring buffer, where it will later be fetched by the background program. It is true that there's not much time between bytes, but once the whole protocol has been received there is usually plenty of time to decode, calculate CRC and so on.

    That's how most old school MCU applications out there look like. Although it is not uncommon to design a setup where you let the interrupt trigger on the first byte and then poll remaining bytes from inside the ISR while allowing other interrupts to execute.

    On modern MCUs you would not use UART RX interrupts but DMA, which solves the whole problem. So on new design which needs to support high baudrates, you would definitely aim for a MCU with DMA support.