原教程: https://devzone.nordicsemi.com/tutorials/6/
在SDK12.0.0或者更高的版本中,对RTT的日志记录调试是内置到记录器模块(logger module NRF_LOG)。想使用RTT的日志记录,检查配置向导(configuration wizard)的sdk_config.h文件的NRF_LOG_BACKEND_SERIAL_USES_RTT 选项。
因此,下面记录的方法主要用于SDK11或者更久远的版本。
当我们创建一个工程的时候,通常需要调试和监视代码的执行。如果我们想要调试,有几个选项,例如在串行端口打印信息,或者在keil中使用断点并单步运行。不过,对于带有蓝牙协议栈这样的实时操作系统的程序来说,这些法子都不怎么能工作。想要在串行端口上记录下标准日志,可以尝试使用SEGGER的实时终端。下面上正题,来谈谈如何将这种调试功能添加到现有的项目中。
1、将RTT文件添加到项目
在网上下载RTT文件
将RTT文件解压复制到工程目录下
在C/C++选项卡包含路径
在项目的主要.c文件顶部包含 #include "SEGGER_RTT.h"
将RTT中的SEGGER_RTT.c文件加入工程
2、简单应用
现在可以通过RTT发送简单的字符串了:
SEGGER_RTT_WriteString(0,"hello!\r\n");
第一个参数是将字符串写入的通道(channel)。
不过我们更经常使用的是另一个函数:
SEGGER_RTT_printf(0,"hello:%d %s\r\n", a, s);
这个函数的功能更强大,使用就和printf一样。它在SEGGER_RTT_printf.c文件中。但是它在中断中使用过多常常会无法正常打印,或者直接不打印。
编译运行一下
3、打开实时终端
现在,代码可以将数据输出到RTT,我们需要能看到它。方法有很多。最方便的一种是使用J-Link软件包附带的RTT查看器。(j-Link RTT Viewer)
打开J-Link RTT Viewer。如下。如果有多个设备连接,请检查序列号(Serial no),然后输入您想要连接的设备的序列号。
单击“确定”。显示如下:
现在,下载你的程序到设备上,就能看到终端上显示“Hello!”。
注意,如果你打开终端,并不会影响串口打印。你可以使用ble_app_uart 工程来建造的项目,在这个项目中向RTT发送文本以进行调试。
请记住,SEGGER_RTT_WriteString()比printf快的多,因此您可以安全地调用此函数,而不影响应用程序的实时性。
4、更高级的打印
来详细讲讲之前提到的SEGGER_RTT_printf()函数。为了能够使用它,稍微修改一下项目:
将文件SEGGER_RTT_printf.c加入到项目中
加入文件RTT_Syscalls_KEIL.c(文件在keil_v5\ARM\Pack\NordicSemiconductor\Syscalls)
去掉工程中的retarget文件(工程目录的nRF_Libraries文件夹下,如下)
在选项卡的 target选项中取消勾线Use MicroLIB
然后就可以使用了,如下:在主程序中:
char c = 0; for (;;) { c = SEGGER_RTT_WaitKey(); // will block until data is available if(c == 'r'){ SEGGER_RTT_printf(0, "%sResetting in %d second..%s\n", RTT_CTRL_BG_BRIGHT_RED, 1, RTT_CTRL_RESET); nrf_delay_ms(1000); sd_nvic_SystemReset(); } //power_manage(); }
编译运行。
注意:如上例程,可以通过在第三个参数写入 RTT_CTRL_BG_BRIGHT_RED 来控制该输出语句的颜色。如下 Terminals 0 所示:
注意:我们常用的rintf()函数其实是定向输出到RTT的。ble_app_uart 项目能够依然按照预期工作,因为它是使用 app_uart_put() 输出到串行端口。
使用printf的例子:
SEEGGER_RGG_printf(0, "variable value: %d\r\n", variable);
第一个参数指定输出的通道,第二个参数是要打印的字符串,variable变量的值插入%d.