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 */
}
}
}
receivingBuffershould bevolatile: It is shared between an ISR and normal code. When you change that, put your compiler warnings to the maximum, because I'm seeing that there will be more than one "discards volatile qualifier". - alxmainshould beint main(void)and the ISRvoid uart_isr(void)(now it's an implicitint, and it is not returning, so you have some problems) - alx-Wall -Wextra -Werrorwill block your compilation - alx