【简介】
RTT(Real Time Transfer)是 SEGGER 为 J-Link 调试器提供的实时日志传输组件,在 J-Link 生态中与 RTT Viewer、Ozone 等工具配合使用非常方便。调试阶段需要打印日志时,RTT 通过 SWD 接口在目标芯片 RAM 中维护上行/下行环形缓冲区,由 J-Link 直接读写,不占用 UART,也不需要额外接 USB 转 TTL,更不依赖 SWO/ITM 引脚;因此在 1ms 甚至更高频率下输出日志也不容易像 115200 串口那样拥塞。RTT 的移植适配也很简单,只需把 SEGGER_RTT.c、SEGGER_RTT.h、SEGGER_RTT_Conf.h和 SEGGER_RTT_printf.c 加入工程,再把printf的 fputc 重定向到 SEGGER_RTT_PutChar 即可,首次调用 RTT 函数会自动完成控制块初始化。本地使用 J-Link V8.60 驱动,源码可在安装目录 C:\Program Files\SEGGER\JLink\Samples\RTT\SEGGER_RTT_Vxxx.zip 中获取。本次我就在立创·天空星 STM32F407VET6 + JLink-OB + Keil HAL 工程上完成 RTT 移植,并用 J-Link RTT Viewer 验证高速 printf 日志输出。
下面正式开始:先介绍一用到的软硬件
硬件部分1. 立创·天空星 STM32F407VGT6 开发板2. JLink-OB 调试器3. 杜邦线 3~4 根软件部分1. Keil MDK5(HAL 库工程,ARM Compiler 6,勾选 Use MicroLIB)2. J-Link Software and Documentation Pack V8.60(内含 RTT Viewer 和 RTT 源码包)
3. SEGGER RTT 源码包 所在位置为下图

把压缩包的源码加入到工程编译,解决掉相关的编译问题就完成了RTT的代码适配

RTT 最直接的用法是 SEGGER_RTT_WriteString(0, "...")和 SEGGER_RTT_printf(0, "...", x),首次调用任意 RTT 函数时会自动完成控制块初始化。不过更舒服的是把标准库 printf 直接重定向过去,已有的串口调试代码一行不用改:注意如果使用keil mdk的话 请打开MicroLIB ac6的话不打开使用printf会卡死 大家记得勾选上
#include <stdio.h>
#include "SEGGER_RTT.h"
/* printf 重定向到 RTT 通道 0 */
int fputc(int ch, FILE *f)
{
(void)f;
SEGGER_RTT_PutChar(0, (char)ch);
return ch;
}
下面我测试一下RTT顺便点个灯

测试代码如下
/* USER CODE BEGIN 2 */
printf("\r\n==== SkyStar F407 RTT Demo ====\r\n");
printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
printf("LED toggled, tick = %d ms\r\n", HAL_GetTick());
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */编译烧录完毕,然后 我们打开J-Link RTT Viewer软件看一下效果 可以看到我们使用的printf打印的数据都显示出来了

至此,我们就在立创天空星STM32F407上成功用上了 SEGGER RTT:不占串口、不接 USB 转 TTL,一根 SWD 线同时搞定下载和调试日志。
大家按照我的思路去移植支持J-link的芯片几乎都可以使用RTT,对于一些串口少的芯片真的十分好用,替大家节省下来一个串口,这样的调试不烧心。
我要赚赏金
