Correct way to implement uart receive buffer in a small ARM microcontroller?

I am looking for ideas for a receive buffer for a small application dealing with 15-byte packets at 921.6 Kbaud compared to rs485. I am thinking of using a circular buffer as the interface between the UART ISR and main. Since this is a microprocessor, I wanted to put

while (uartindex!=localindex) { do stuff } 

at

while (;;) {do forever} 

part of the core, but I was told that this is unacceptable.

How do people deal with their uart under similar circumstances?

+5
source share
2 answers

ISR must fill in FIFO. Home should consume it.

Insert a very simple fifo algorithm:

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

(Care must be taken when using this FIFO algorithm, size must be 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 */
    }    
}
+4

, , , uartindex ( , ), localindex .

, 2, 32- ; "stuff", "fetch". ,

(unsigned)(uartindex-localindex) 

, , , N- N-1.

, , , , .

+2

All Articles