# STM32F04xx UART - Implement input rejection for strings longer than 2 bytes

I am trying to implement input validation on the STM32 side. I am hoping to allow a string in the form "x\n" where "x" can be any character.

To receive a changing number of bytes I have implemented this in USART1_IRQHandler

void USART1_IRQHandler(void)
{
if((USART1->ISR & USART_ISR_RXNE) != RESET) {
if((1+RX_BUFFER_POS) < RX_BUFFER_SIZE) {
UART_Buffer[1+RX_BUFFER_POS++] = USART1->RDR; // reading from DR resets RXNE flag, no need to manually clear it!
}
}
HAL_UART_IRQHandler(&huart1);
}


And in the main while loop of the program

if((RX_BUFFER_POS + 1) >= 2) {
if(UART_Buffer[1] == 0x0A && !(UART_Buffer[2])) {
HAL_UART_Transmit_IT(&huart1, (uint8_t*)OK_BUFFER, OKBUFFERSIZE);
} else {
UART_Buffer[2] = 0;
RX_BUFFER_POS = -1;
}
RX_BUFFER_POS = -1;
}


The code correctly rejects an invalid character string, I use "00\n" as an example, the first time. After that all strings are rejected, including a "valid" ("x\n") string.

I did some debugging, and found that after an incorrect string, RX_BUFFER_POS was not being reset to -1, instead it stuck at 0. What is the cause of this? I also found that if I added a 1ms delay to the main while loop, the problem was fixed. This makes me suspect that some sort of race condition is occuring.

A side note, I found a way to fix any character being rejected. If I send a string of length 7, with "\n" being the last character the rejection will work once more. When I send the string I receive "BAD" and also "OK".

My question is why is RX_BUFF_POS not being reset to -1 when an incorrect string is received? Also, as there seems to be a race condition occuring, how can I track down the cause of this?

• For this unique case, I'd be tempted to build a tiny state machine which would hold a received character in a static char temporarily and only write it to the buffer if the following newline is seen on the next interrupt, otherwise discard it. You could then go as far as to put the valid characters alone in the buffer, without the newlines, since only those so accompanied would get that far. But if your messages might ever need to become variable length, this optimization would not easily extend. – Chris Stratton Mar 7 '18 at 18:06
• What you may not (yet) have noticed is that you 'RX_BUFFER_POS' is changed in both the ISR and in the main program but is not protected from interrupts in the latter. – Oldfart Mar 7 '18 at 18:53