Search code examples
cembeddedfifointeger-overflow

FIFO Queue in Embedded C - Counters will overflow?


so I'm reading a textbook on RTOS and there's a section that talks about FIFO queue's. I want to implement the code provided in the book for a UART device. I looked through the code and saw that the counters in the code don't reset. The counters are 32 bits, so they can go up to 2^32, but what if they were to be implemented in a device that goes past that value? If the counters overflow, will they wrap around and continue working normally as counters?

#include <stdint.h>

#define Size 32 //temporary value. It can be any value 2^n

uint32_t volatile TxPutI;//Counter 1
uint32_t volatile TxGetI;//Counter 2
static char TxFifo[size];
void TxFifo_Init(void)
{
    TxPutI = TxGetI = 0;
}
int TxFifo_Put(char data)
{
    if( (TxPutI - TxGetI)&~(Size-1) )
        return 0;
    TxFifo[TxPutI&(Size-1)] = data;
    TxPutI++; //it can overflow
    return 1;
}
int TxFifo_Get(char *datapt)
{
    if( TxPutI == TxGetI )
        return 0;
    *datapt = TxFifo[TxGetI & (Size-1)];
    TxGetI++; //it can overflow
    return 1;
}
uint16_t TxFifo_Size(void) //If someone can explain how this work, that'd be awesome!
{
    return( (uint16_t)(TxPutI - TxGetI) );
}

A special condition in the book is that the value Size must be 2^n. Does this condition keep the counters from causing an incorrect index? Thank you


Solution

  • It doesn't matter if these counters overflow. The arithmetic "just works" due to the properties of unsigned arithmetic. When a difference is taken, the operation does a "borrow" from the unrepresented upper bits, and the low bits of the result are correct. Since the difference must be much smaller than the max value of the type uint32_t the upper bits of the difference are always zero.

    Here's an example using uint8_t to avoid large numbers. We'll use uint8_t getI and putI variables, and a FIFO with size 16. getI and putI start out at 0. After 263 insertions and 254 removals, getI is 254 and putI is 7 (263 - 256 due to overflow). In unsigned arithmetic, 7 - 254 is 9. Work through some examples!

    In the implementation given, the size of the FIFOs must also be a power of two because bitwise is used for modulo operations, and the cute trick for testing to see if the FIFO is full.