通过J-Link RTT为ARM Cortex-M搭建命令行界面
要在不使用UART的情况下通过SWD实现命令行界面,请使用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 Viewer
安装SEGGER J-Link软件包。从C:\Program Files\SEGGER\JLink_V834运行JLinkRTTViewer.exe。
配置连接:
- 选择SWD或JTAG。
- 指定目标设备(ARM Cortex-M)。
- 设置速度(最高兆赫兹)。
- 确认连接。
在终端0中输入命令——支持颜色高亮。如果FIFO溢出,请编辑SEGGER_RTT_Conf.h以增加缓冲区大小。
通过TCP替代访问
RTT Viewer在127.0.0.1:19021上打开一个套接字(使用netstat -ano | grep 19021检查)。
使用PuTTY或Tera Term连接:
- 主机:127.0.0.1
- 端口:19021
- 类型:TCP
这模拟了一个UART终端。可通过WiFi网络远程工作。
RTT CLI的优势与局限
优势:
- 与逐步调试并行操作。
- 无需ELF文件:烧录后传递给J-Link。
- 以SWD速度即时传输。
- 复制粘贴带高亮的日志。
- 多个终端。
局限:
- 依赖J-Link(不适用于AVR/ESP32/RISC-V)。
- MCU复位时断开连接——需要手动重连。
- 单独的输入窗口(通过TCP解决)。
- Viewer不支持\r(Tera Term中可用)。
| 方面 | SWD RTT | UART |
|--------|-------------|------|
| 速度 | SWD MHz | 115200+ |
| 引脚 | 3-4 | 2+ |
| 调试 | 并行 | 否 |
| 复位 | 断开连接 | 稳定 |
关键要点
- 在main()之前初始化RTT以进行早期日志记录。
- 使用NO_BLOCK_SKIP避免挂起。
- 通过tx/rx_cnt日志监控FIFO溢出。
- TCP 19021解决UI Viewer问题。
- 适用于支持J-Link的Cortex-M。
— Editorial Team
暂无评论。