
- TX 링버퍼 전역 변수들
#define TX_BUF_SZ 512
static uint8_t tx_buf[TX_BUF_SZ];
static volatile uint16_t tx_head = 0;
static volatile uint16_t tx_tail = 0;
static volatile uint8_t tx_busy = 0;
static volatile uint32_t tx_ovf = 0;
static uint8_t tx_it_byte;
- tx_buf[512]
- tx_head / tx_tail
- 원형 큐 포인터
- head : 다음에 넣을 위치
- tail : 다음에 뺄 위치
- tail == head → 빔
- tx_busy
- 현재 UART가 IT(인터럽트) 송신 진행 중인지 표시
- 1이면 이미 송신 중 → 새로 HAL_UART_Transmit_IT() 걸면 안됨
- 0이면 idle → 첫 바이트 송신 시작
- tx_ovf
- 버퍼가 꽉 차서 유실 된 횟수
- 값이 증가하면 출력량이 UART 대역폭보다 크다는 뜻
- tx_it_byte
- HAL_UART_Transmit_IT()는 메모리 주소를 넘겨야 함
- 링버퍼에서 pop한 1바이트를 잠깐 담아둘 실제 변수 필요
- tx_rb_push() : 링버퍼에 1바이트 넣기
static void tx_rb_push(uint8_t b){
uint16_t next = (uint16_t)((tx_head + 1) % TX_BUF_SZ);
if(next == tx_tail) { tx_ovf++; return; }
tx_buf[tx_head] = b;
tx_head = next;
}
- next 먼저 계산 이유 : head를 한 칸 앞으로 옮겼을 때 tail과 같아지면 full로 간주
- next == tx_tail이면 버퍼가 꽉 참 → tx_ovf++하고 드롭
- 안멈추면 head가 tail을 덮어서 데이터 구조 박살남
- tx_rb_pop() : 링버퍼에서 1바이트 빼기
static int tx_rb_pop(uint8_t *out){
if(tx_tail == tx_head) return 0;
*out = tx_buf[tx_tail];
tx_tail = (uint16_t)((tx_tail + 1) % TX_BUF_SZ);
return 1;
}
- 비어있으면 0리턴
- 있으면 *out에 넣고 tail을 앞으로 이동 후 1 리턴