Jlink可以下载程序、读取寄存器,RTT窗口却一直空着,这种情况并不少见。调试连接建立后,程序还得真正执行输出,电脑端也得找到对应的内存位置,文字才能显示出来。下面以SEGGER RTT和J-Link RTT Viewer为例,说明工程配置、缓冲区设置以及无输出时的检查方法。
一、Jlink怎样启用RTT实时输出并设置缓冲区
RTT通过目标芯片RAM中的控制块和环形缓冲区交换数据。对于支持后台内存访问的目标,通常可以沿用现有调试接口,不需要另外连接串口线或SWO引脚。
1、让工程实际执行一次输出
将SEGGER_RTT.c、SEGGER_RTT.h及配套配置文件加入工程;使用SEGGER_RTT_printf时,还要加入对应实现文件。调用处包含头文件,在启动阶段完成初始化,再用SEGGER_RTT_WriteString向通道0写入一条短消息。
验证时可以让这条消息低频重复输出。只在上电瞬间打印一次,等终端打开后再观察,很容易分不清程序没执行,还是数据已经错过。普通printf若没有重定向,也不会自动进入RTT。
2、在工程里调整缓冲区
默认通道0的大小由编译配置决定。电脑端打开更多终端标签,并不会增加目标芯片上的日志存储空间。
①打开工程实际使用的SEGGER_RTT_Conf.h,将【BUFFER_SIZE_UP】设为适合日志量的容量,例如1024字节。
②需要接收电脑输入时,再检查【BUFFER_SIZE_DOWN】;仅输出日志时,不必同步扩大下行缓冲区。
③重新编译并下载,核对下载文件与刚才修改的构建配置一致。
通道0应通过编译配置调整容量。按照当前官方实现说明,调用SEGGER_RTT_ConfigUpBuffer配置通道0时,除标志外的配置参数会被忽略。
3、连接RTT Viewer
独立运行Viewer和附着到IDE现有调试会话,是两种连接方式。IDE已经使用J-Link时,可以借用该会话读取RTT。
①启动J-Link RTT Viewer;独立连接时选择实际探针、完整芯片型号及调试接口,接口速度沿用已验证稳定的设置。
②附着到IDE时,在【Connection to J-Link】中选择【Existing Session】。
③确认程序正在运行,连接后切换到【All Terminals】观察输出。
二、Jlink连接正常但RTT终端没有数据如何排查
排查时先留下那条低频短消息,暂时绕开业务日志框架。这样可以把日志等级、任务调度和格式化过程带来的影响缩小,检查结果也更容易判断。
1、确认输出语句有没有执行
在RTT写入语句附近设置断点,观察程序是否到达这里。停在main入口时,后面的初始化和输出当然还没发生;程序反复复位,也可能始终走不到日志任务。
如果直接调用RTT能够显示,业务日志仍然没有内容,就顺着日志开关、编译宏和输出后端继续查。此时反复更换探针接口速度,通常解决不了问题。
2、核对控制块地址
自动搜索并不覆盖所有RAM。控制块被链接到另一块内存后,J-Link可能仍能正常调试,却找不到RTT。应从本次构建的映射文件中查找_SEGGER_RTT,别沿用其他工程里的地址。
①在Viewer连接配置的【RTT Control Block】区域选择【Address】,填写_SEGGER_RTT的实际地址。
②若使用【Search Range】,填写控制块所在且允许调试访问的RAM范围。
③重新连接,并让程序执行RTT初始化和输出。
这里填写的是控制块地址,不能拿某个字符数组的地址代替。扩大搜索范围前,也要确认相关内存已经启用且可以访问。
3、分清通道与终端标签
程序向通道1写入文字,不代表Viewer的Terminal 1就会显示。虚拟终端标签共享通道0,而通道1是另一条数据通道。
①点击【All Terminals】,检查通道0的完整输出。
②核对RTT写入函数的缓冲区索引,基础验证时使用0。
③如果程序调用过SEGGER_RTT_SetTerminal,再打开对应的【Terminal 0】至【Terminal 15】标签查看。
三、RTT有输出后怎样检查丢行和运行停顿
能看到文字,只能说明基本链路已经通了。日志量增大后出现缺行,或者拔掉探针后程序卡住,还需要回到缓冲区满时的处理方式。
1、按程序要求选择满缓冲策略
非阻塞Skip模式在空间不足时丢弃本次写入;Trim模式写入能容纳的部分,剩余内容丢弃。阻塞模式则等待空间,日志读取不及时,等待就可能持续下去。
①检查工程的【SEGGER_RTT_MODE_DEFAULT】,确认当前选择。
②需要优先维持任务运行时,可评估【SEGGER_RTT_MODE_NO_BLOCK_SKIP】或【SEGGER_RTT_MODE_NO_BLOCK_TRIM】。
③使用【SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL】前,验证终端关闭、探针断开时程序能否接受等待。
2、用连续序号检查输出
测试日志里加入递增序号,比盯着窗口判断“有没有少几行”更直接。分别记录低负载和集中打印时的结果,再决定扩大缓冲区还是减少输出频率。
①在Viewer中点击【Logging】→【Start Terminal Logging】,保存通道0日志。
②运行包含日志突发输出的测试,检查文件中的序号是否连续。
如果平均写入量一直大于读取量,增加缓冲区只能延后丢失。缩短重复消息、降低打印频率,往往更适合长期运行的程序。
总结
RTT窗口空白时,先让程序向通道0重复写一条短消息,再核对控制块地址和终端标签,检查起来会清楚很多。输出恢复后,也别急着把所有日志打开,还要看看忙时是否丢行、终端关闭后是否影响任务。希望这些检查方法能帮助大家找到故障发生的位置,留下适合当前工程的配置。若有相关使用需求,欢迎进一步交流。