임베디드 시스템을 개발하다 보면 외부 장치와 데이터를 주고받는 방법으로 가장 많이 쓰이는 것이 UART입니다. 특히 간단한 시리얼 통신 예제에서는 RXNE 플래그만 확인해서 데이터를 읽는 방식이 자주 사용되죠.

대부분의 경우 이 방식으로 충분합니다. 하지만 조금 더 까다로운 상황에서는 문제가 생길 수 있습니다.

예를 들어, 외부 장치가 내 장치의 응답 여부와 상관없이 짧은 간격으로 많은 데이터를 계속 보내는 경우를 생각해봅시다. 이때 단순히 RXNE 처리만 한다면 시스템이 안정적으로 동작하지 않을 수 있습니다.

이번 글에서는 이러한 상황에서도 시스템이 정상적으로 부팅하고 안정적으로 동작할 수 있도록 만드는 방법을 정리해 보겠습니다.


문제 상황: 왜 부팅 중에 시스템이 멈출까?

실제 테스트에서, 외부 장치가 부팅 과정 동안 계속 데이터를 송신할 때 내 장치가 부팅 도중 멈추는 현상을 발견했습니다.

원인을 추적해 보니, 다음과 같은 흐름이 있었습니다:

  1. 외부 장치가 데이터를 송신 → MCU에서 Rx Interrupt 발생
  2. MCU가 데이터를 받아야 하는데, 아직 초기화 과정이 끝나지 않음
  3. ISR 처리를 못 해서 Overrun Error 발생
  4. 에러 플래그가 처리되지 않아 부팅이 멈춤

즉, 단순히 RXNE만 처리해서는 부족하고, Overrun Error(ORE)Frame Error(FE) 같은 오류 상황까지 고려해야 한다는 결론에 도달했습니다.


해결 방법: Error Flag 처리 추가하기

이 문제를 해결하려면 Error Flag를 클리어해 주는 처리가 필요합니다.

특히 ORE와 FE는 데이터가 정상적으로 처리되지 않았음을 의미하므로, 해당 플래그를 클리어하고 Dummy Read를 통해 버퍼를 비워주는 것이 안정적인 방법입니다.

이렇게 하면, 부팅 중이든 동작 중이든 예상치 못한 데이터 폭주 상황에서도 시스템이 멈추지 않고 정상적으로 동작할 수 있습니다.


예제 코드: USART2 ISR 수정하기

아래는 USART2를 기준으로 작성한 ISR 코드입니다. 다른 UART 포트에도 동일한 방법으로 적용할 수 있습니다.


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);
    }
}

여기서 핵심은 ORE와 FE 처리입니다. 이 두 가지를 추가해 주는 것만으로도,

“부팅 중 멈춤 현상” 같은 치명적인 문제가 사라지고 시스템이 훨씬 안정적으로 동작합니다.


결론

UART를 사용할 때 단순히 RXNE만 확인하는 예제 코드는 대부분의 상황에서 충분합니다. 하지만 외부 장치가 빠르게 데이터를 쏟아내는 상황에서는 꼭 Error Flag 처리를 추가해야 합니다.

  • ORE(Overrun Error): 데이터를 제때 읽지 못했을 때 발생
  • FE(Frame Error): 데이터 프레임 이상이 발생했을 때 발생
  • 해결 방법 → 해당 플래그를 클리어 + Dummy Read

이렇게 간단한 보완만 해도, 시스템이 훨씬 안정적으로 동작합니다.


0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

ko_KRKorean