05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계 (1)

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계

UART 통신, 단순히 printf만 찍고 계신가요? 하드웨어 의존성을 제거하고 유연한 펌웨어를 만들기 위한 4단계 계층 분리 설계법을 공개합니다.

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계

신입 사원 시절, 저도 `HAL_UART_Transmit` 함수 하나로 모든 걸 해결하려 했던 적이 있습니다. 하지만 기능이 늘어날수록 메인 루프가 버벅거리고, 하드웨어를 바꾸면 코드를 다 엎어야 하는 대참사가 일어났죠. 오늘은 그 '스파게티 지옥'에서 탈출하는 아키텍처 설계법을 배워볼게요! 😊

1. 왜 함수 호출 하나로 통신하면 안 될까요? 🤔

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계

코드 중간에 `HAL_UART_Transmit`을 직접 넣는 방식은 이른바 'Blocking' 방식입니다. 데이터가 전송될 때까지 CPU가 아무것도 못 하고 기다려야 하죠.

💡 핵심 설계 원칙
통신 매체(UART)와 데이터 처리 로직(Protocol)은 철저히 분리되어야 합니다. 그래야 UART를 SPICAN으로 바꿔도 로직은 그대로 유지할 수 있습니다.

 

2. 펌웨어 통신의 4단계 계층 구조 📊

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계

전문가들은 통신을 아래와 같은 계층으로 나누어 관리합니다. 각 단계가 독립적일수록 유지보수가 쉬워집니다.

계층 역할 비고
Low Level (HAL) UART ISR/DMA를 통한 데이터 수신 하드웨어 종속
Buffer Layer Ring Buffer에 데이터 임시 저장 충격 완화 장치
Parser Layer 패킷 시작/끝 확인 및 유효성 검사 프로토콜 정의
Application 해석된 명령에 따른 기능 수행 비즈니스 로직
⚠️ 주의하세요!
인터럽트(ISR) 안에서 복잡한 파싱 로직을 수행하지 마세요. ISR은 오직 데이터를 버퍼로 옮기는 일만 해야 합니다.

 

3. 실전 코드 적용: 링 버퍼 인터페이스 👩‍💻

📝 핵심 아키텍처 코드

// 1. 하드웨어 추상화를 위한 구조체 정의
typedef struct {
    void (*Transmit)(uint8_t *pData, uint16_t Size);
    uint8_t (*ReceiveByte)(void);
    bool (*IsDataAvailable)(void);
} CommInterface;

// 2. Ring Buffer를 통한 비동기 처리
void UART_ISR_Callback() {
    uint8_t data = HAL_UART_Receive_IT(&huart1);
    RingBuffer_Put(&rxBuffer, data); // 버퍼에 던져두고 즉시 탈출!
}

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계

이렇게 구성하면 PC 시뮬레이터 환경에서도 `CommInterface`의 함수 포인터만 바꿔 끼워 통신 로직을 완벽하게 테스트할 수 있습니다.

🔢 통신 지연시간 계산기

보레이트 (Baudrate):
데이터 크기 (Bytes):

마무리: 핵심 내용 요약 📝

오늘 배운 내용은 펌웨어 개발자로서 '레벨 업'하기 위한 필수 관문입니다.

💡

UART 모듈화 3계명

✨ 탈종속화: HAL 함수를 직접 호출하지 마세요. 인터페이스 레이어를 두어 하드웨어 독립성을 확보해야 합니다.
📊 비동기화: Ring Buffer는 필수입니다. 수신은 인터럽트로, 처리는 메인 루프에서 분리하세요.
👩‍💻 테스트 가능성: 로직이 분리되면 하드웨어 없이도 유닛 테스트가 가능해집니다.

자주 묻는 질문 ❓

05강. [실습] UART 통신 모듈화: printf 말고 통신 프로토콜 설계
Q: Ring Buffer 크기는 어느 정도가 적당한가요?
A: 예상되는 최대 패킷 크기의 최소 2~4배 이상을 권장합니다. 메모리가 허용한다면 2의 승수(256, 512 등)로 설정하여 연산 속도를 높일 수 있습니다.
Q: DMA를 쓰는 게 무조건 좋은 거 아닌가요?
A: 대용량 데이터 전송에는 유리하지만, 가변 길이 패킷 수신 시에는 Idle Line 인터럽트와 결합해야 하므로 설계가 복잡해질 수 있습니다. 상황에 맞게 선택하세요.
다음 이전