Search code examples
cbufferinterruptstm32uart

Handling UART ISR during double buffer swap


I am working on a double buffer for the UART on a STM32F processor. The example below adds the data to a buffer every time the UART ISR runs. This buffer is then swapped when the main process wants to pull data off of it.

I am concerned about a possible corner condition. It is possible for the ISR to fire after I have swapped the buffers but before I have reset the receive buffer count. This would mean that my buffer size and count would be out of sync.

What is the best way to handle this corner case?

uint8_t rxBufferA[MAX_RX_BUFFER_SIZE];
uint8_t rxBufferB[MAX_RX_BUFFER_SIZE];
uint8_t *receivingBuffer;
uint8_t *processingBuffer;
volatile uint32_t rxBufferSize;

uart_isr() {
  receivingBuffer[rxBufferSize++] = RECEIVE_DATA_REGISTER
}


main() {

  receivingBuffer = &rxBufferA;
  processingBuffer = &rxBufferB;

  while(1) {

    if (rxBufferSize > 0) {
      uint32_t i = 0;
      uint8_t *ptemp = receivingBuffer;
      uint8_t bufferSize = 0;

      /* zero out processing buffer */
      memset(processingBuffer, 0, MAX_RX_BUFFER_SIZE);

      /* swap receiving and processing buffers */
      receivingBuffer = processingBuffer
      processingBuffer = ptemp;

      /* WHAT IF THE ISR FIRES HERE??? */         

      /* save off buffer size and reset count */
      bufferSize = rxBufferSize;
      rxBufferSize = 0;

      /* process rx data */
    } 
  }
}

Solution

  • you need critical section. disable the user interrupt when swapping the buffer.

    BTW zeroing is not needed