ISR は FIFO を埋める必要があります。メインはそれを消費する必要があります。
非常に単純な 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;
(この FIFO アルゴリズムには注意が必要です。サイズは 2 の累乗でなければなりません)
ISR は次のように動作する必要があります。
void ISR_Handler()
{
uint8_t c;
while(UART_NotEmpty()) {
c = UART_GetByte();
RINGFIFO_WR(gUartFifo, c);
}
}
そしてメイン:
while(1)
{
if (!RINGFIFO_EMPTY(gUartFifo)) {
/* consume fifo using RINGFIFO_RD */
}
}
このアルゴリズムは、FIFO をメイン ループから直接読み取ります。中間層を使用して、バッファにフル パケットがあるかどうかを確認し、main が次のようになるように処理する必要があります。
uint8_t ptrToPacket;
uint32_t packetSize;
while(1)
{
if (!Uart_HasValidPacket()) {
Uart_GetPacket(&ptrToPacket, &packetSize)
/* Process packet using ptrToPacket and packetSize */
}
}