When developing embedded systems, one of the most common ways to exchange data with external devices is through UART. In many basic serial communication examples, the typical approach is simply checking the RXNE flag to read incoming data.
In most situations, this works fine. However, in more demanding scenarios, issues may arise.
For instance, imagine an external device that keeps transmitting large amounts of data at very short intervals, regardless of whether your system is ready to respond. In such cases, just relying on RXNE is not enough to guarantee stable operation.
In this post, we’ll explore how to make sure your system can boot and run reliably, even under these conditions.
The Problem: Why Does the System Hang During Boot?
During testing, we observed that when an external device continuously transmitted data during boot, the system sometimes froze during startup.
Tracing the cause revealed the following sequence:
- The external device transmits data → Rx Interrupt occurs on the MCU
- The MCU should read from the internal buffer, but initialization isn’t finished yet
- The ISR cannot be serviced → Overrun Error occurs
- The error flag is not cleared → system hangs
In other words, just handling RXNE isn’t enough. You also need to take care of errors like Overrun Error (ORE) and Frame Error (FE).
The Solution: Handle Error Flags
To prevent this issue, you must clear error flags properly.
Both ORE and FE indicate abnormal reception conditions. The fix is simple: clear the corresponding flag and perform a Dummy Read to flush the buffer.
With this in place, the system can continue working normally, even if data floods in during boot or runtime.
Example Code: Updating the USART2 ISR
Here’s an example of how the ISR for USART2 can be modified. The same principle applies to any UART port.
void USART2_IRQHandler(void)
{
if (LL_USART_IsActiveFlag_ORE(USART2))
{
LL_USART_ClearFlag_ORE(USART2);
LL_USART_ReceiveData8(USART2); // Dummy Read
}
if (LL_USART_IsActiveFlag_FE(USART2))
{
LL_USART_ClearFlag_FE(USART2);
LL_USART_ReceiveData8(USART2); // Dummy Read
}
if (LL_USART_IsActiveFlag_RXNE(USART2))
{
LL_USART_ReceiveData8(USART2);
}
if (LL_USART_IsActiveFlag_TXE(USART2))
{
// TX Empty 처리
}
if (LL_USART_IsActiveFlag_TC(USART2))
{
LL_USART_ClearFlag_TC(USART2);
}
}
The critical addition here is handling ORE and FE. By clearing these flags and flushing the buffer,
you eliminate the risk of “system hang during boot” and greatly improve overall stability.
Summary
Using UART with just the RXNE check is usually enough for basic applications. But in scenarios where the external device transmits data at a high rate, you need to take extra steps:
- ORE (Overrun Error): occurs when data isn’t read in time
- FE (Frame Error): occurs when a data frame is invalid
- Solution → Clear the error flag and perform a Dummy Read
With this simple enhancement, your system will run far more reliably under heavy UART traffic.
0 Comments