Search code examples
embeddedmicrocontrollercircular-bufferdouble-buffering

Choosing between double buffer and ring buffer?


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?

Solution

  • 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.