ARM Cortex-M용 J-Link RTT를 통한 CLI 셸 설정하기
UART 없이 SWD를 통해 CLI를 구현하려면 SEGGER_RTT 라이브러리를 사용하세요. 소스 파일을 다운로드하세요: SEGGER_RTT.h (API, 253줄), SEGGER_RTT.c (구현, 1751줄), SEGGER_RTT_printf.c (printf, 516줄), SEGGER_RTT_Conf.h (설정, 333줄).
제로 RTT 채널 초기화부터 시작하세요:
void SeggerInit() {
SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
SEGGER_RTT_ConfigDownBuffer(0, "RTTDOWN", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
SEGGER_RTT_SetTerminal(0);
}
bool segger_rtt_init_custom(void) {
bool res = true;
SeggerInit();
return res;
}
펌웨어 시작 시 SeggerInit()을 호출하여 논블로킹 송수신 버퍼를 구성하세요.
들어오는 명령 처리하기
메인 루프나 타이머에서 SEGGER_RTT_Read를 통해 채널을 주기적으로 폴링하세요:
bool segger_rtt_proc_one(uint8_t num) {
bool res = false;
LOG_PARN(SEGGER_RTT, "RTT%u,Proc", num);
SeggerRttHandle_t* Node = SeggerRttGetNode(num);
if(Node) {
if(Node->RxBuffer) {
if(Node->buffer_size) {
unsigned rx_byte = SEGGER_RTT_Read(Node->BufferIndex,
Node->RxBuffer,
Node->buffer_size);
if(rx_byte) {
res = segger_rtt_writer(num);
LOG_DEBUG(SEGGER_RTT,"RxData:[%s]=[%s],rxByteCnt:%u Bytes",
ArrayToStr(Node->RxBuffer,rx_byte),
ArrayToAsciiStr(Node->RxBuffer,rx_byte),
rx_byte);
res = cli_process_data(Node->cli_num,
Node->RxBuffer,
rx_byte);
memset(Node->RxBuffer, 0, rx_byte);
}
}
}
}
return res;
}
함수는 수신된 바이트 수를 반환합니다. 데이터를 CLI 핸들러에 전달하세요: cli_process_data().
펌웨어에서 응답 전송하기
문자열을 전송하려면 SEGGER_RTT_Write를 사용하세요. putc/puts 및 FIFO 버퍼용 함수를 구현하세요:
void segger_rtt1_puts(void* stream_ptr, const char* str, int32_t len) {
SeggerRttHandle_t* Node = SeggerRttGetNode(1);
if(Node) {
if(str) {
if(len) {
unsigned tx_cnt = SEGGER_RTT_Write(Node->BufferIndex,
(void* ) str,
(unsigned) len);
(void)tx_cnt;
}
}
}
}
void segger_rtt1_putc(void* stream_ptr, char ch) {
SeggerRttHandle_t* Node = SeggerRttGetNode(1);
if(Node) {
unsigned tx_cnt = SEGGER_RTT_Write(Node->BufferIndex,
(void* ) &ch,
(unsigned) 1);
(void)tx_cnt;
}
}
Tx FIFO에서 데이터를 추출하여 RTT 채널에 기록하세요. 이렇게 하면 데이터 손실 없이 비동기 전송이 보장됩니다.
- FIFO 장점: 버퍼링으로 피크 부하 시 오버플로를 방지합니다.
- 모니터링:
tx_cnt를 로깅하여 누락된 전송을 디버깅하세요. - 확장성: 다중 채널 지원 (num > 0).
PC에서 J-Link RTT 뷰어 구성하기
SEGGER J-Link 패키지를 설치하세요. C:\Program Files\SEGGER\JLink_V834에서 JLinkRTTViewer.exe를 실행하세요.
연결을 구성하세요:
- SWD 또는 JTAG를 선택하세요.
- 대상 장치를 지정하세요 (ARM Cortex-M).
- 속도를 설정하세요 (메가헤르츠까지).
- 연결을 확인하세요.
터미널 0에 명령을 입력하세요 — 색상 강조를 지원합니다. FIFO 오버플로가 발생하면 SEGGER_RTT_Conf.h를 편집하여 버퍼 크기를 늘리세요.
TCP를 통한 대체 접근
RTT 뷰어는 127.0.0.1:19021에 소켓을 엽니다 (netstat -ano | grep 19021로 확인).
PuTTY나 Tera Term을 사용하여 연결하세요:
- 호스트: 19021
- 유형: TCP
이것은 UART 터미널을 에뮬레이트합니다. WiFi 네트워크를 통해 원격으로 작동합니다.
RTT CLI의 장점과 한계
장점:
- 단계별 디버깅과 병렬 작동.
- ELF 파일 불필요: 플래시 후 J-Link에 전달.
- SWD 속도로 즉시 전송.
- 강조 표시된 로그 복사-붙여넣기.
- 다중 터미널.
단점:
- J-Link 의존성 (AVR/ESP32/RISC-V 미지원).
- MCU 리셋 시 연결 끊김 — 수동 재연결 필요.
- 별도의 입력 창 (TCP로 해결).
- 뷰어에서 \r 미지원 (Tera Term에서 사용 가능).
| 측면 | SWD를 통한 RTT | UART |
|--------|-------------|------|
| 속도 | MHz SWD | 115200+ |
| 핀 | 3-4 | 2+ |
| 디버깅 | 병렬 | 아니오 |
| 리셋 | 연결 끊김 | 안정적 |
핵심 포인트
- 초기 로깅을 위해 main() 전에 RTT를 초기화하세요.
- 멈춤을 피하려면 NO_BLOCK_SKIP을 사용하세요.
- tx/rx_cnt 로그로 FIFO 오버플로를 모니터링하세요.
- TCP 19021로 UI 뷰어 문제를 해결하세요.
- J-Link 지원 Cortex-M에 적합합니다.
— Editorial Team
아직 댓글이 없습니다.