2

Ring buffers are the go to choice by most veteran embedded programmers for asynchronous communications. Assume that data arrives over UART from only a single source and only when a msg is asked for(Master->Slave,Slave->Master), since codes are sequential in nature, we can just implement an ordinary array(max size of data received) to hold the received data. Like so:

#define MAX_SIZE 8
U8 RxBuff[MAX_SIZE]

Once data has been processed and replied,the master and slave can reset the RxBuff.There is no need for a Ring Buffer.

But this got me thinking,do Ring Buffers offer the advantage of a longer SRAM life? I have read that memories like Flash,Ram have limited write cycles but infinite read cycles. By implementing a Ring Buffer that circles around RAM locations every time data arrives,does such an implementation, by reducing the write cycles for constant memory locations of the RxBuff everytime data is received,offer improved memory life?

Or are there other reasons why Ring Buffers are preferred?

AlphaGoku
  • 1,013
  • 2
  • 11
  • 27
  • Your second assumption is critical here (input is only replies); also your third assumption that the recieved data is small. If either of those is violated what happens to the RX buffer? And it's not true that SRAM has a limited write cycle. – pjc50 Mar 18 '16 at 10:32
  • In a Master-Slave design,the Master knows the size of the packet that its going to send and the slave will know the size of the packet its receives and vice versa right? If the received data is smaller that MAX_SIZE, the Reset RxBuffer will have to affect the memory loc that contains data to clear it. The probability that RxBuff[0] has to be cleared is 100%. Okay,thanks for clearing the doubt on SRAM. So SRAM has infinite write & Read cycles. – AlphaGoku Mar 18 '16 at 10:37
  • What happens if the data is corrupted in transit or you lose the end-of-message marker? Are all the messages the same size - this isn't true of AT-style command sets? – pjc50 Mar 18 '16 at 10:47
  • What happens if the data is corrupted in transit or you lose the end-of-message marker?-How does Ring Buffer solve this. Are all the messages the same size - this isn't true of AT-style command sets?- The MAX_SIZE will be set based on the max size of data that can be expected to be received – AlphaGoku Mar 18 '16 at 10:51
  • 1st, assume a spherical cow :) ... Its dangerous to make to many assumptions with serial comms. Your 1st assumption should be 'if it can go wrong it will', and work from there. – brhans Mar 18 '16 at 13:57

2 Answers2

2

FLASH and EEPROM memory do have endurance issues with multiple writes to the same location, but that doesn't affect RAM which is where you'd normally store a ring buffer for async communications. The main two reasons I can think of are:

  • Many common protocols don't follow the sequential command / response sequence you describe. For example GPS receivers send a fairly continuous stream so it's important to be able to continue to receive data while the previous data is processed.

  • Because ring buffers are often required for those sort of protocols it becomes more convenient to use them for all async comms. The only real extra overhead is needing both a queue tail and head which in many cases will only be a single byte.

Given your constraints if writing to RAM then simply resetting the buffer at the end of a message and starting again from the start of the buffer would be fine. But the uses are so limited and the advantages so small most would prefer to just use a ring buffer in all applications.

PeterJ
  • 17,201
  • 37
  • 57
  • 91
  • But even for the first point you mentioned, the new data must not overwrite the data being processed when the Head pointer wraps around i.e if msg 1 in buffer is being processed by tail pointer but the header pointer is overwriting the Buffer in ISR. – AlphaGoku Mar 18 '16 at 10:54
  • In that case if you don't process it in time you'll get some data loss regardless of whether it gets overwritten or you ignore further data rather than overwriting it. You need a buffer size in either case that is large enough to be processed by the main code before the ISR fills the buffer. But for something like the GPS example that has delimiters it will self-correct if that delay is only occasional. – PeterJ Mar 18 '16 at 11:01
2

First of all, as others have pointed out any communication buffers would be in RAM, not flash or EEPROM, so there is no issue of the memory wearing out.

The main reason I see to use ring buffers for communication, is when you use an interrupt service routine (ISR) to handle the incoming characters. The ISR is the producer, and the base level (non-interrupt) is the consumer. Along with the ring buffer there are two pointers, one for the character location to store the next incoming character, and a second pointer to keep track of the last character retrieved from the buffer. When the pointers are equal, the buffer is empty.

enter image description here

By using a ring buffer, the system can handle characters coming in at a high rate (e.g. every 87 µs for 115.2 KBaud), and not worry whether they are processed right away (assuming the buffer is large enough to handle the delay between receiving and retrieval).

This would be important, for example, in a non-preemptive RTOS where a task switch does not occur until the current task voluntarily gives up control to the OS. Meanwhile the ISR will be collecting characters in the background, and when the task switch does occur, presumably the task to process the incoming characters would be run next.

tcrosley
  • 48,066
  • 5
  • 98
  • 162
  • It would be better to use a dispatcher to place data of various sources in separate ring buffers as the uC has to identify the data belongs to which source when maybe receiving data via UART in multidrop maybe. As long as the producer for the data does not produce data continuously, a ring buffer may not be needed i guess. But by implementing a ring buffer, i see the benefit that,in the event that the source produces data continuously, the Rx function needs no changes – AlphaGoku Mar 18 '16 at 11:54