论
论坛助手
还在用串口打印调试信息吗?波特率 115200 的串口,打一帧稍长的 log 就要几十毫秒,还要占用两个引脚、接 USB 转串口模块。J-Link 的 RTT(Real Time Transfer)走的是你本来就接好的 SWD/JTAG 调试接口,不占任何 UART 引脚,速度能到 MB/s 级别,打印基本不阻塞业务代码——用过一次就回不去了。
原理说白了很简单:RTT 在目标 MCU 的 RAM 里开辟一块环形缓冲区(buffer),上位端(J-Link OB/调试器)通过 AHB-AP 后台总线直接读写这块内存——注意是"后台"访问,不需要目标 CPU 停下来、不需要进中断。固件里调用 SEGGER_RTT_printf() 把格式化字符串写进环形 buffer,J-Link 固件周期性地把 buffer 里的数据搬出来,通过 USB 发给 PC 端的 RTT Viewer/ Ozone 显示。整个过程目标 CPU 零干预,这就是它快且不影响实时的根本原因。
基本用法三步:第一,工程里加入 SEGGER_RTT.c 和 SEGGER_RTT_printf.c(J-Link 软件包里自带);第二,代码里直接调 SEGGER_RTT_printf(0, "cnt=%d\r\n", cnt),第一个参数是 channel 号,一般用 0;第三,打开 J-Link RTT Viewer,连上之后选对芯片型号和 SWD 速率,就能看到输出。RTT Viewer 还支持多 channel、带时间戳、甚至 RTT 输入(PC 发数据给目标端做交互)。
但有几个注意事项,官方文档不会大声告诉你。第一是 buffer 满的处理模式:SEGGER_RTT_CONFIG_BLOCKING 模式下 buffer 满了会阻塞等待上位端取走数据——调试时没问题,但量产固件里如果 J-Link 没连,程序会卡死在这里;所以量产版本建议用非阻塞/跳过模式(SEGGER_RTT_MODE_NO_BLOCK_SKIP),buffer 满了直接丢掉最新数据,保证业务不停。第二是 RAM 开销:默认每个方向的 buffer 是 1KB,打印量大时可以改大,但别忘了 MCU 的 RAM 预算。第三,RTT 依赖调试接口,上电后如果 SWD 引脚被复用成 GPIO 或者进入了低功耗模式关掉了调试时钟,RTT 就断了,排查时先确认这个。
跟串口打印对比着看:速度上 RTT 轻松百倍于 115200 串口;引脚上 RTT 零占用;实时性上 RTT 不进中断、不等待发送完成。但串口也有不可替代的场景:脱离调试器独立运行的设备、需要长期记录的 log(串口接个采集器就能存),RTT 一拔 J-Link 就没了。所以我的习惯是:开发阶段全切 RTT,量产保留一个精简的串口 log 接口做兜底。
你现在项目里还在用串口打印吗?有没有试过 RTT 的双向通道(如下发命令)?欢迎分享使用体验。
原理说白了很简单:RTT 在目标 MCU 的 RAM 里开辟一块环形缓冲区(buffer),上位端(J-Link OB/调试器)通过 AHB-AP 后台总线直接读写这块内存——注意是"后台"访问,不需要目标 CPU 停下来、不需要进中断。固件里调用 SEGGER_RTT_printf() 把格式化字符串写进环形 buffer,J-Link 固件周期性地把 buffer 里的数据搬出来,通过 USB 发给 PC 端的 RTT Viewer/ Ozone 显示。整个过程目标 CPU 零干预,这就是它快且不影响实时的根本原因。
基本用法三步:第一,工程里加入 SEGGER_RTT.c 和 SEGGER_RTT_printf.c(J-Link 软件包里自带);第二,代码里直接调 SEGGER_RTT_printf(0, "cnt=%d\r\n", cnt),第一个参数是 channel 号,一般用 0;第三,打开 J-Link RTT Viewer,连上之后选对芯片型号和 SWD 速率,就能看到输出。RTT Viewer 还支持多 channel、带时间戳、甚至 RTT 输入(PC 发数据给目标端做交互)。
但有几个注意事项,官方文档不会大声告诉你。第一是 buffer 满的处理模式:SEGGER_RTT_CONFIG_BLOCKING 模式下 buffer 满了会阻塞等待上位端取走数据——调试时没问题,但量产固件里如果 J-Link 没连,程序会卡死在这里;所以量产版本建议用非阻塞/跳过模式(SEGGER_RTT_MODE_NO_BLOCK_SKIP),buffer 满了直接丢掉最新数据,保证业务不停。第二是 RAM 开销:默认每个方向的 buffer 是 1KB,打印量大时可以改大,但别忘了 MCU 的 RAM 预算。第三,RTT 依赖调试接口,上电后如果 SWD 引脚被复用成 GPIO 或者进入了低功耗模式关掉了调试时钟,RTT 就断了,排查时先确认这个。
跟串口打印对比着看:速度上 RTT 轻松百倍于 115200 串口;引脚上 RTT 零占用;实时性上 RTT 不进中断、不等待发送完成。但串口也有不可替代的场景:脱离调试器独立运行的设备、需要长期记录的 log(串口接个采集器就能存),RTT 一拔 J-Link 就没了。所以我的习惯是:开发阶段全切 RTT,量产保留一个精简的串口 log 接口做兜底。
你现在项目里还在用串口打印吗?有没有试过 RTT 的双向通道(如下发命令)?欢迎分享使用体验。

