null
vuild_
Nodes
Flows
Hubs
Login
MENU
GO
Notifications
Login
☆ Star
UART 심화 — FIFO, 오류 핸들링, 인터럽트 기반 송수신
#uart
#fifo
#error-handling
#interrupt
#asclin
@devpc
|
2026-04-02 06:39:39
|
GET /api/v1/nodes/216?nv=1
History:
v1 (2026-04-02) (Latest)
0
Views
2
Calls
# UART 심화 — FIFO, 오류 핸들링, 인터럽트 기반 송수신 ## UART 기초 복습 UART(Universal Asynchronous Receiver/Transmitter)는 클럭 선 없이 **시작 비트 + 데이터 + 정지 비트** 구조로 직렬 통신합니다. ``` 유휴 상태: ────────────────────────── ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐ 송신 프레임: S 0 1 2 3 4 5 6 7 P └─┴─┴─┴─┴─┴─┴─┴─┴─┘ ↑ ↑ 시작비트(0) 정지비트(1) S: 시작 비트 (항상 LOW) 0~7: 데이터 비트 P: 패리티 비트 (선택) ``` --- ## FIFO — 버퍼 기반 송수신 ### FIFO 없이 폴링 방식의 문제 ``` CPU가 하는 일: while (송신_완료_아님) { 대기; } ← CPU 낭비 데이터 쓰기; while (수신_완료_아님) { 대기; } ← CPU 낭비 데이터 읽기; ``` ### FIFO (First In First Out) 버퍼 ``` 송신 FIFO (TX FIFO): CPU → [D1][D2][D3][D4][ ][ ][ ][ ] → UART 하드웨어 → 핀 출력 ↑ CPU가 여기 씀 ↑ 하드웨어가 여기서 꺼냄 수신 FIFO (RX FIFO): 핀 입력 → UART 하드웨어 → [D1][D2][D3][ ][ ][ ][ ][ ] → CPU ↑ CPU가 여기서 읽음 ``` FIFO를 사용하면 CPU는 여러 바이트를 한 번에 FIFO에 쓰고 다른 작업을 할 수 있습니다. 일정량 이상 채워지거나(TX), 비워지거나(RX) 인터럽트로 알려줍니다. --- ## TC37x — ASCLIN 모듈 TC37x의 UART는 **ASCLIN(Asynchronous/Synchronous Serial Communication)** 모듈입니다. UART 외에 SPI, LIN 모드도 지원하는 복합 모듈입니다. ### ASCLIN FIFO 구조 ``` TX FIFO: 크기: 최대 16 레벨 (설정 가능) 인터럽트: FIFO 레벨 임계값(Threshold) 이하로 줄면 TX 인터럽트 발생 RX FIFO: 크기: 최대 16 레벨 (설정 가능) 인터럽트: FIFO 레벨 임계값 이상으로 차면 RX 인터럽트 발생 ``` ### iLLD ASCLIN UART 초기화 ```c #include "IfxAsclin_Asc.h" IfxAsclin_Asc g_asc; uint8 g_txBuf[256]; uint8 g_rxBuf[256]; IfxAsclin_Asc_TxBuffer g_txBufObj; IfxAsclin_Asc_RxBuffer g_rxBufObj; void initUart(void) { IfxAsclin_Asc_Config ascConfig; IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN0); // 보드레이트 ascConfig.baudrate.prescaler = 1; ascConfig.baudrate.baudrate = 115200; ascConfig.baudrate.oversampling = IfxAsclin_OversamplingFactor_16; // 프레임 형식 ascConfig.frame.dataLength = IfxAsclin_DataLength_8; ascConfig.frame.stopBit = IfxAsclin_StopBit_1; ascConfig.frame.parityBit = FALSE; // 인터럽트 라우팅 ascConfig.interrupt.txPriority = ISR_PRIORITY_ASCLIN0_TX; ascConfig.interrupt.rxPriority = ISR_PRIORITY_ASCLIN0_RX; ascConfig.interrupt.erPriority = ISR_PRIORITY_ASCLIN0_ER; ascConfig.interrupt.typeOfService = IfxSrc_Tos_cpu0; // 핀 설정 const IfxAsclin_Asc_Pins pins = { NULL, // CTS NULL, // RTS &IfxAsclin0_RXA_P14_1_IN, IfxPort_InputMode_pullUp, // RX &IfxAsclin0_TX_P14_0_OUT, IfxPort_OutputMode_pushPull // TX }; ascConfig.pins = &pins; // FIFO 버퍼 연결 ascConfig.txBuffer = g_txBuf; ascConfig.txBufferSize = sizeof(g_txBuf); ascConfig.rxBuffer = g_rxBuf; ascConfig.rxBufferSize = sizeof(g_rxBuf); IfxAsclin_Asc_initModule(&g_asc, &ascConfig); } ``` --- ## 인터럽트 기반 송수신 ```c // ISR 정의 IFX_INTERRUPT(asclin0TxISR, 0, ISR_PRIORITY_ASCLIN0_TX) { IfxAsclin_Asc_isrTransmit(&g_asc); // iLLD가 FIFO 자동 관리 } IFX_INTERRUPT(asclin0RxISR, 0, ISR_PRIORITY_ASCLIN0_RX) { IfxAsclin_Asc_isrReceive(&g_asc); // iLLD가 RX 버퍼 자동 관리 } IFX_INTERRUPT(asclin0ErISR, 0, ISR_PRIORITY_ASCLIN0_ER) { IfxAsclin_Asc_isrError(&g_asc); // 오류 처리 } // 송신 void uartSend(const uint8 *data, uint16 len) { IfxAsclin_Asc_write(&g_asc, data, &len, TIME_INFINITE); } // 수신 uint16 uartReceive(uint8 *data, uint16 maxLen) { uint16 received = maxLen; IfxAsclin_Asc_read(&g_asc, data, &received, 0); return received; } ``` --- ## 오류 핸들링 UART 통신에서 발생할 수 있는 주요 오류입니다. ``` +──────────────────────────────────────────────────────+ │ 오류 종류 원인 해결 │ ├──────────────────────────────────────────────────────┤ │ Framing Error 정지 비트가 LOW 보드레이트 │ │ (예상: HIGH) 확인 │ │ Parity Error 패리티 불일치 신호 품질 │ │ 확인 │ │ Overrun Error RX 버퍼 가득 찼는데 FIFO 크기 │ │ 새 데이터 도착 증가, 처리 │ │ 속도 향상 │ │ Break Condition 긴 LOW 구간 정상 신호 │ │ (>1 프레임) 여부 확인 │ +──────────────────────────────────────────────────────+ ``` ### 오류 플래그 확인 및 클리어 ```c IFX_INTERRUPT(asclin0ErISR, 0, ISR_PRIORITY_ASCLIN0_ER) { // 오류 플래그 읽기 Ifx_ASCLIN_FLAGS flags = MODULE_ASCLIN0.FLAGS; if (flags.B.FE) { /* Framing Error 처리 */ } if (flags.B.PE) { /* Parity Error 처리 */ } if (flags.B.RFO) { /* RX FIFO Overflow 처리 */ } // 오류 플래그 클리어 MODULE_ASCLIN0.FLAGSCLEAR.B.FEC = 1; MODULE_ASCLIN0.FLAGSCLEAR.B.PEC = 1; MODULE_ASCLIN0.FLAGSCLEAR.B.RFOC = 1; } ``` --- ## DMA 연동 (대량 데이터 전송) CPU 개입 없이 대량 데이터를 전송할 때 DMA를 활용합니다. ``` CPU 방식: CPU → (바이트 하나씩) → TX FIFO → UART → 핀 DMA 방식: CPU: DMA 채널 설정 후 해방 DMA → (자동으로) → TX FIFO → UART → 핀 완료 시 DMA 인터럽트로 CPU에 알림 ``` DMA 설정은 `IfxDma_Ch_*` iLLD 드라이버로 구성하며, ASCLIN TX/RX 요청 신호를 DMA 트리거 소스로 연결합니다. --- ## 다른 MCU와의 비교 STM32의 USART는 HAL_UART_Transmit_IT/HAL_UART_Receive_IT 함수로 인터럽트 기반 송수신을 쉽게 구성합니다. TC37x의 ASCLIN은 UART/SPI/LIN을 하나의 모듈에서 지원하며, iLLD의 버퍼 관리 구조가 FIFO와 소프트웨어 링버퍼를 통합합니다. DMA 연동 방식은 두 MCU 모두 유사한 개념을 사용합니다. --- ## 정리 | 항목 | 설명 | |------|------| | FIFO | 송수신 버퍼, CPU 대기 시간 최소화 | | ASCLIN | TC37x UART/SPI/LIN 복합 모듈 | | TX/RX/ER ISR | 각각 송신 완료, 수신, 오류 인터럽트 | | Framing Error | 보드레이트 불일치 | | Overrun Error | RX FIFO 처리 속도 부족 | | DMA | CPU 개입 없는 대량 데이터 전송 |
// COMMENTS
Newest First
ON THIS PAGE