关于嵌入式C中的FIFO队列:嵌入式C中的FIFO队列-计数器会溢出吗?

FIFO Queue in Embedded C - Counters will overflow?

所以我正在阅读一本有关RTOS的教科书,其中有一部分讨论FIFO队列。我想实现本书中为UART设备提供的代码。我浏览了一下代码,发现代码中的计数器没有重置。计数器是32位的,因此它们可以达到2 ^ 32,但是如果要在超过该值的设备中实现它们又该怎么办呢?如果计数器溢出,它们会环绕并继续作为计数器正常工作吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#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) );
}

书中的一个特殊条件是"大小"值必须为2 ^ n。这种情况是否可以防止计数器导致错误的索引?谢谢


这些计数器是否溢出无关紧要。由于无符号算术的特性,算术"正常工作"。取差时,操作会从未表示的高位开始"借用",并且结果的低位是正确的。由于差值必须比类型uint32_t的最大值小得多,所以差值的高位始终为零。

下面是使用uint8_t避免大量数字的示例。我们将使用uint8_t getIputI变量,以及大小为16的FIFO。getIputI从0开始。在263次插入和254次删除之后,getI是254和为7(由于溢出,为263-256)。在无符号算术中,7-254为9。

在给定的实现中,FIFO的大小也必须为2的幂,因为按位用于模运算,还有测试FIFO是否已满的可爱技巧。