Met*_*ode 6 arm circular-buffer uart
我正在寻找一个小型应用程序的接收缓冲区的想法,该应用程序通过rs485处理921.6Kbaud的15字节数据包.我正在考虑使用循环缓冲区作为UART ISR和main之间的接口.因为它是一个我想放的微处理器
while (uartindex!=localindex) { do stuff }
Run Code Online (Sandbox Code Playgroud)
在里面
while (;;) {do forever}
Run Code Online (Sandbox Code Playgroud)
部分主要但我被告知这是不可接受的.
人们如何在类似情况下处理他们的蠢货?
ISR应填写FIFO.主要应该消耗它.
Bellow一个非常简单的fifo算法:
#define RINGFIFO_SIZE (1024) /* serial buffer in bytes (power 2) */
#define RINGFIFO_MASK (RINGFIFO_SIZE-1ul) /* buffer size mask */
/* Buffer read / write macros */
#define RINGFIFO_RESET(ringFifo) {ringFifo.rdIdx = ringFifo.wrIdx = 0;}
#define RINGFIFO_WR(ringFifo, dataIn) {ringFifo.data[RINGFIFO_MASK & ringFifo.wrIdx++] = (dataIn);}
#define RINGFIFO_RD(ringFifo, dataOut){ringFifo.rdIdx++; dataOut = ringFifo.data[RINGFIFO_MASK & (ringFifo.rdIdx-1)];}
#define RINGFIFO_EMPTY(ringFifo) (ringFifo.rdIdx == ringFifo.wrIdx)
#define RINGFIFO_FULL(ringFifo) ((RINGFIFO_MASK & ringFifo.rdIdx) == (RINGFIFO_MASK & (ringFifo.wrIdx+1)))
#define RINGFIFO_COUNT(ringFifo) (RINGFIFO_MASK & (ringFifo.wrIdx - ringFifo.rdIdx))
/* buffer type */
typedef struct{
uint32_t size;
uint32_t wrIdx;
uint32_t rdIdx;
uint8_t data[RINGFIFO_SIZE];
} RingFifo_t;
RingFifo_t gUartFifo;
Run Code Online (Sandbox Code Playgroud)
(必须注意这个FIFO算法,大小必须是2的幂)
ISR应该像这样:
void ISR_Handler()
{
uint8_t c;
while(UART_NotEmpty()) {
c = UART_GetByte();
RINGFIFO_WR(gUartFifo, c);
}
}
Run Code Online (Sandbox Code Playgroud)
主要:
while(1)
{
if (!RINGFIFO_EMPTY(gUartFifo)) {
/* consume fifo using RINGFIFO_RD */
}
}
Run Code Online (Sandbox Code Playgroud)
这个算法直接从主循环中读取FIFO,你应该使用一个中间层来检查缓冲区中是否有一个完整的数据包,并以这样的方式处理它,这样main将是这样的:
uint8_t ptrToPacket;
uint32_t packetSize;
while(1)
{
if (!Uart_HasValidPacket()) {
Uart_GetPacket(&ptrToPacket, &packetSize)
/* Process packet using ptrToPacket and packetSize */
}
}
Run Code Online (Sandbox Code Playgroud)
uartindex如果从未在主循环中写入(除了在禁用中断时初始化它)并且localindex从未被中断例程触及, 您建议的方法可能是可行的。
我建议您将缓冲区大小设置为 2 的幂,对两个索引使用无符号整数,并允许它们在完整的 32 位大小上自由计数;在“stuff”和“fetch”例程中索引缓冲区时使用位掩码。如果你这样做,那么
(unsigned)(uartindex-localindex)
Run Code Online (Sandbox Code Playgroud)
应指示缓冲区中有多少个字符,即使缓冲区已满,也不需要在缓冲区已满的情况下采取特殊行为,并且不限制 N 字节缓冲区容纳 N-1 个项目。
请注意,虽然上述表达式中的类型转换并不是严格必要的,但我建议将其包括在内,因为它显然表明减去无符号数量时的包装行为是有意且预期的。
| 归档时间: |
|
| 查看次数: |
10081 次 |
| 最近记录: |