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

标签 c embedded fifo integer-overflow

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

#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) );
}

书上有一个特殊的条件,就是Size的值必须是2^n。这种情况是否可以防止计数器导致不正确的索引?谢谢

最佳答案

这些计数器是否溢出并不重要。由于无符号算术的特性,算术“有效”。当取差时,该操作从未表示的高位“借”,结果的低位是正确的。由于差异必须远小于类型 uint32_t 的最大值,因此差异的高位始终为零。

这是一个使用 uint8_t 来避免大数的示例。我们将使用 uint8_t getIputI 变量,以及大小为 16 的 FIFO。getI putI 从 0 开始。经过 263 次插入和 254 次删除后,getI 为 254,putI 为 7(263 - 256 由于溢出)。在无符号算术中,7 - 254 是 9。通过一些例子来完成!

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

关于c - 嵌入式 C 中的 FIFO 队列 - 计数器会溢出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47404432/

相关文章:

c# - 使用 FIFO 进行过滤

c - 堆内存澄清

c - 如何在没有换行符的情况下缓冲从大文件读取的数据

c - 在 MCU 上使用 nmealib 安全吗?

C#:需要一个类似于 Java 的 LinkedBlockingQueue 的阻塞 FIFO 队列

java - 同步 FIFO 缓冲区使用

c - 在文件中插入文本而不是在c中覆盖

c - USB 24 位音频流描述符

embedded - avrdude 和 atmega48pa

c - 遗产库