当前位置:网站首页>【嵌入式】使用JLINK RTT打印log

【嵌入式】使用JLINK RTT打印log

2022-07-06 08:40:00 好奇宝宝·权

没有串口的情况下可以使用JLINK的RTT即 Real Time Transfer功能。RTT的工作原理大致就是在内存里面创建一个RTT控制块RTT Control Block,即SEGGER_RTT_CB结构体。这个结构体里面存放了若干个上行通道和下行通道,每个通道都有一个数据buffer以及读写指针,构成了数据队列。向RTT控制块里面的任意一个上行通道的数据队列中写入log信息,然后JLINK能够通过读写RAM内容,获取到队列的数据buffer和写指针的内容,并更新读指针。如果写入的数据太快,JLINK的刷新速率来不及读取队列内容的话,可能导致队列满,数据丢失情况,可以适当加大上传队列的长度:BUFFER_SIZE_UP,在配置文件SEGGER_RTT_Conf.h中。

在JLINK的安装目录里面有RTT的代码:

可以直接使用SEGGER_RTT_Write函数写字符串:

SEGGER_RTT_Write(0, "0123456789", 10);

或者使用SEGGER_RTT_printf进行格式化打印:

SEGGER_RTT_printf(0, "%s\n", "test");

使用RTTViewer工具可以通过JLINK实时读取RAM内容获取上传通道的数据内容:

由于需要获取芯片RAM中的数据,那就得要知道要读取的RAM地址,也就是RTT Control Block的地址。RTT Control Block的结构体定义为:

typedef struct {
  char                    acID[16];                                 // Initialized to "SEGGER RTT"
  int                     MaxNumUpBuffers;                          // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2)
  int                     MaxNumDownBuffers;                        // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2)
  SEGGER_RTT_BUFFER_UP    aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS];       // Up buffers, transferring information up from target via debug probe to host
  SEGGER_RTT_BUFFER_DOWN  aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS];   // Down buffers, transferring information down from host via debug probe to target
} SEGGER_RTT_CB;

程序定义了一个RTT Control Block变量:_SEGGER_RTT

SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));

其中acID会被初始化为固定字符串值:“SEGGER RTT”,可以用这个字符串做为Magic Number,在整个RAM空间里面搜索到RTT Control Block的位置,但是有点傻。找到编译生成的map文件,查找_SEGGER_RTT的位置:

 然后在RTT Viewer里面connect的时候设置RTT control block地址为_SEGGER_RTT的地址:

运行结果:

RTT Viewer终端支持显示不同字符颜色以及清空屏幕指令,SEGGER_RTT.h中有控制指令定义,使用方式示例:

SEGGER_RTT_Write(0, RTT_CTRL_BG_BLACK RTT_CTRL_TEXT_RED "0123456789", 20);

SEGGER_RTT_printf(0, RTT_CTRL_BG_GREEN RTT_CTRL_TEXT_YELLOW "%s\n", "test");

运行结果:

有点不方便的是每次在data段添加变量的时候,数据的内存地址可能会改变,那么_SEGGER_RTT的地址就会变化,这样每次都要查看_SEGGER_RTT的地址,比较麻烦,可以使用attribute关键字指定_SEGGER_RTT变量存放在内存的位置,注意要避开启动文件中默认分配的stack的地址区域和heap地址区域,例如这里我改成:

//SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
SEGGER_RTT_CB _SEGGER_RTT __attribute__ ((at(0x1FFE4000)));

原网站

版权声明
本文为[好奇宝宝·权]所创,转载请带上原文链接,感谢
https://blog.csdn.net/tq384998430/article/details/125015552