better way to buffer uart

Discussion in 'Programmer's Corner' started by bug13, Apr 15, 2018.

  1. bug13

    Thread Starter Senior Member

    Feb 13, 2012
    Hi guys

    I find myself quite often need to buffer a packet of data from uart, then the main application will need to process them. Here is how I usually do it.

    Code (Text):
    1. typedef struct{
    2.     uint8_t data[MAX_SIZE];
    3.     uint8_t pointer;                              // pointing to next empty location in a buffer
    4.     uint8_t isReady : 1;                       // set if the buffer is ready to be processed
    5.     uint8_t isBeingWriten : 1;              // set if the buffer is being written to, usually in a interrupt.
    6.     // maybe other flags
    7. }my_struct_t;
    9. volatile my_struct_t my_struct[BUFFER_LEVEL];
    11. // return the index of an empty buffer, return 0xFF if no empty bubfer
    12. uint8_t findEmptyBufferIndex(void){
    13.     // disable uart interrupt
    14.     // do stuff
    15.     // enable uart interrupt
    16. }
    18. // return the index of a buffer that is ready to be processed by the main application., return 0xFF if there is no buffer to be processed
    19. uint8_t findReadyBufferIndex(void){
    20.     // disable uart interrupt
    21.     // do stuff
    22.     // enable uart interrupt
    23. }

    Is there better way to do this?
  2. WBahn


    Mar 31, 2012
    The common way of dealing with needs like this is to push the received packets into a FIFO and then pull them from the FIFO. That isolates the data producer from the data consumer as long as the FIFO is large enough either to never fill up (if you want to be able to always service incoming data that can't be throttled) or ever go empty (if you want to be able to consume data at a constant rate). In the case of most UART traffic, it doesn't take much of a FIFO to pull this off, perhaps just two slots even, as long as the system pulling data is responsive.
    bug13 likes this.
  3. MrChips


    Oct 2, 2009
    You could use a circular buffer but I use a simple array.
    The basic premise is that :

    1) Information comes in as a packet and the maximum length of the packet is predetermined.
    2) Packets have [start] and [end] characters.
    3) The processor can handle packets faster than the rate at which they arrive.

    The packet is processed only after the [end] character has been received.
    I never disable interrupts.
    bug13 likes this.
  4. bug13

    Thread Starter Senior Member

    Feb 13, 2012
    Thanks guys, I will look into both suggestions.