0
votes

I have a problem of decoding a packet which is sent through UART of a micro controller (The firmware needs to be baremetal, no RTOS support). The packet is 32 bytes long, and is send at every 10 milliseconds (continuously, without any stop).

I need to do very minimal processing in ISR (to keep the ISR short enough) and do the deferred processing in main() loop. There are two approaches coming to my mind - 1. Use a interrupt-safe ring buffer with ISR writing into the buffer and main() loop reading from it. The head and tail pointer are assumed to be atomic types of my architecture, so as to make sure that the buffer is interrupt-safe. See a sample implementation here.

  1. Use a double buffering scheme(ping-pong buffer), wherein the main() loop shall process one of the buffer while the ISR is writing to the other. Assume that i can atomically modify the pointer to the ISR buffer, so that the critical section problem is avoided.

The UART is capable of generating RX FIFO not-empty interrupt. Also DMA support is available.

  1. Which is the optimal datastructure to use here?
  2. What is the tradeoff involved here?
1
What would be the criteria for switching buffers in the double buffer approach? I guess you have a sort of "start packet" character that would do that? From a first glance, that looks a bit more complicated than a simple ring buffer with not much benefit. Also recovering from a missed "packet start" looks more difficult to me.tofro
The double buffer requires the ISR to decode the protocol and switch buffers. By contrast, the ring buffer doesn’t need the ISR to decode the protocol BUT some code must read sufficiently quickly from the read end of the ring to avoid it filling up: that code will typically copy the data into another buffer, parsing the protocol and keeping recognised packets. IMO ring buffer is less demanding on the ISR.balmy

1 Answers

3
votes

A double buffer is just a special kind of ring buffer with only two slots that are exchanged between producer and consumer. If your processing times don't vary much, it should be enough. A ring buffer can be helpful if input rates or processing times vary, but then you would most likely need some flow control to slow down input rate when processing can't keep up.