0

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?
SRK
  • 308
  • 3
  • 16
  • 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 Feb 12 '19 at 23:03
  • 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. – DisappointedByUnaccountableMod Feb 14 '19 at 22:38

1 Answers1

3

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.

  • Can you explain why double-buffer wont be a good option if input rates or processing rates vary? – SRK Feb 12 '19 at 10:14
  • If they vary enough that the producer could fill two slots in the time required by the consumer to process one, there wouldn't be a free slot to use. – Hans-Martin Mosner Feb 12 '19 at 10:17
  • Well yes that’s true, but in the end it’s probably no different than the thing you criticise about ring buffer: that something will fail if processing can’t keep up. – DisappointedByUnaccountableMod Feb 14 '19 at 22:36
  • And a ring buffer and “double buffer” are not so similar as you suggest. A ring buffer doesn’t need the ISR to decode the protocol, whereas a “double buffer” does. So I wouldn’t take this as the simple default correct answer. – DisappointedByUnaccountableMod Feb 14 '19 at 22:38
  • It’s quite simple to maintain separate read and write pointers into a ring buffer - the ISR only modifies the write pointer, the mainline only modifies the read pointer. By contrast switching buffers is much more complex. – DisappointedByUnaccountableMod Feb 14 '19 at 22:42
  • @barny We can think of ping-pong buffer as a special case of a ring buffer with just two entries. But as you pointed out rightly, switching the buffer pointers in a ping-pong buffer is complex. But still i think there are some advantages for ping-pong buffer. They are commonly used in high speed applications, like video and signal processing. What i cant understand is why they prefer ping-pong buffer in these applications, where a ring buffer would have performed equally well. – SRK Feb 15 '19 at 04:00
  • I think the complexity of managing a pingpng might be difficult to debug and justify. – DisappointedByUnaccountableMod Feb 15 '19 at 22:37