在嵌入式开发中,串口打印是常用的调试手段,但串口资源紧张或被占用时,调试效率会大幅下降。Segger JLink 的 RTT(Real Time Terminal)功能可完美解决这一问题 —— 通过 SWD 调试口实现双向高速数据传输,不占用额外外设资源,且不影响系统实时性。本文以 RT595-EVK 开发板为例,详解基于 MCUXpresso IDE 的 RTT 移植全流程,从文件导入到日志输出一步到位,适用于各类无串口或串口紧张的调试场景。
资料获取:RT595移植JLink RTT功能
1. RTT 核心优势与环境准备
1.1 核心优势(对比传统串口 / 半主机模式)
- 资源占用少:无需占用 UART 引脚与外设,仅依赖 SWD 调试口(2 个引脚);
- 传输速度快:远超串口波特率,支持 MB 级每秒传输,且双向通信无延迟;
- 实时性强:不打断 MCU 运行,数据写入 RAM 环形缓冲区后由 JLink 异步读取,不影响系统时序;
- 灵活易用:支持多通道日志输出,无需配置波特率、引脚复用等繁琐步骤;
- 无 OS 依赖:可在裸机或 RTOS 环境下使用,适配各类嵌入式场景。
1.2 软硬件与工具环境
- 硬件:NXP MIMXRT595-EVK 开发板、JLink 调试器(板载或外置)、USB 调试线;
- 软件:MCUXpresso IDE(任意兼容版本)、RT595 SDK(含 Hello_World 基础工程);
- 关键工具:JLink Software Pack(含 RTT 核心文件与 RTT Viewer)。
2. 移植核心步骤
步骤 1:获取 RTT 核心文件
RTT 移植仅需 5 个核心文件,默认存储在 JLink 安装目录下:
- 打开路径:
C:Program FilesSEGGERJLinkSamplesRTT; - 提取文件:
- 头文件:
SEGGER_RTT.h、SEGGER_RTT_Conf.h; - 源文件:
SEGGER_RTT.c、SEGGER_RTT_printf.c、SEGGER_RTT_Syscalls_GCC.c; - 说明:
SEGGER_RTT_printf.c提供格式化打印功能,SEGGER_RTT_Syscalls_GCC.c适配 GCC 编译器(MCUXpresso IDE 默认使用)。
- 头文件:
步骤 2:工程配置(文件导入与路径设置)
(1)导入文件到工程
- 打开 MCUXpresso IDE,加载 RT595 SDK 的
hello_world工程; - 在工程目录下新建
source/RTT文件夹,将提取的 5 个文件复制到该目录; - 右键工程→「Refresh」,确保文件成功加载到工程中。
(2)配置头文件路径(自动识别,无需手动配置)
由于文件直接放在工程source目录下,MCUXpresso IDE 会自动检索头文件,无需额外添加包含路径(若使用 Keil/IAR,需手动添加头文件目录)。
步骤 3:代码集成(初始化与日志打印)
在
hello_world.c中添加 RTT 初始化与打印代码,替换传统串口打印逻辑:(1)完整代码示例
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "SEGGER_RTT.h" // 包含RTT头文件
int main(void) {
/* 1. 系统初始化(沿用SDK默认配置) */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole(); // 可保留,不影响RTT功能
/* 2. RTT初始化与缓冲区配置 */
SEGGER_RTT_Init(); // 初始化RTT模块
// 配置上行缓冲区(MCU→PC):通道0,名称"RTTUP",缓冲区大小32字节,非阻塞模式
uint8_t up_buffer[32];
SEGGER_RTT_ConfigUpBuffer(0,
"RTTUP",
up_buffer,
sizeof(up_buffer),
SEGGER_RTT_MODE_NO_BLOCK_SKIP); // 无数据时跳过,不阻塞
// 配置下行缓冲区(PC→MCU):通道0,名称"RTTDOWN",缓冲区大小32字节,非阻塞模式
uint8_t down_buffer[32];
SEGGER_RTT_ConfigDownBuffer(0,
"RTTDOWN",
down_buffer,
sizeof(down_buffer),
SEGGER_RTT_MODE_NO_BLOCK_SKIP);
/* 3. RTT日志打印(替代printf/DEBUG_CONSOLE_PRINTF) */
SEGGER_RTT_SetTerminal(0); // 选择通道0输出
SEGGER_RTT_printf(0, "RTT移植成功!RT595-EVK调试日志开始输出rn");
SEGGER_RTT_printf(0, "系统时钟频率:%d MHzrn", CLOCK_GetCoreSysClkFreq() / 1000000);
/* 4. 循环打印测试 */
uint32_t count = 0;
while (1) {
SEGGER_RTT_printf(0, "循环计数:%d,RTT日志正常输出rn", count++);
SDK_DelayAtLeastUs(1000000, CLOCK_GetCoreSysClkFreq()); // 延时1秒
}
}
(2)关键 API 说明
SEGGER_RTT_Init():初始化 RTT 模块,创建默认缓冲区;SEGGER_RTT_ConfigUpBuffer():配置 MCU 到 PC 的上行缓冲区(日志输出);SEGGER_RTT_ConfigDownBuffer():配置 PC 到 MCU 的下行缓冲区(指令输入);SEGGER_RTT_printf():格式化打印,用法与printf完全一致;SEGGER_RTT_MODE_NO_BLOCK_SKIP:非阻塞模式,缓冲区满时跳过当前数据,不影响 MCU 运行。
步骤 4:编译工程与硬件连接
- 编译工程:点击 MCUXpresso IDE 的「Build」按钮,确保无编译错误(若提示头文件未找到,检查文件路径是否正确);
- 硬件连接:通过 USB 线连接 RT595-EVK 的板载 JLink 调试口到 PC;
- 烧录固件:点击「Debug」按钮,将编译生成的固件烧录到开发板(烧录流程与普通工程一致)。
步骤 5:RTT Viewer 接收日志
- 打开 JLink RTT Viewer(JLink Software Pack 自带);
- 配置连接参数:
- 目标设备:选择
MIMXRT595SXXXA(RT595 对应型号); - 接口与速率:默认 SWD 模式,速率自动适配(建议 4000kHz);
- 通道选择:默认通道 0(与代码中配置一致);
- 目标设备:选择
- 点击「OK」连接,成功后即可在终端看到日志输出:
RTT移植成功!RT595-EVK调试日志开始输出 系统时钟频率:600 MHz 循环计数:0,RTT日志正常输出 循环计数:1,RTT日志正常输出 ...
3. 关键配置与优化
3.1 缓冲区大小调整(适配日志量)
若日志输出较多,可增大缓冲区大小(默认 32 字节),避免数据丢失:
#define RTT_BUFFER_SIZE 1024 // 定义1KB缓冲区
uint8_t up_buffer[RTT_BUFFER_SIZE];
SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", up_buffer, sizeof(up_buffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
3.2 多通道日志输出(分类调试)
RTT 支持多个独立通道,可按模块分类输出日志:
// 通道0:系统日志
SEGGER_RTT_printf(0, "[系统] 初始化完成rn");
// 通道1:传感器日志
SEGGER_RTT_printf(1, "[传感器] 数据采集成功:%drn", sensor_data);
- 查看方式:在 RTT Viewer 中切换「Terminal 0」「Terminal 1」即可分别查看。
3.3 下行数据接收(PC→MCU)
若需从 PC 向 MCU 发送指令,可通过下行缓冲区读取:
uint8_t rx_data[32];
while (1) {
// 读取下行缓冲区数据(非阻塞)
int32_t len = SEGGER_RTT_Read(0, rx_data, sizeof(rx_data));
if (len > 0) {
SEGGER_RTT_printf(0, "收到PC指令:");
for (int i = 0; i < len; i++) {
SEGGER_RTT_PutChar(0, rx_data[i]);
}
SEGGER_RTT_printf(0, "rn");
}
SDK_DelayAtLeastUs(500000, CLOCK_GetCoreSysClkFreq());
}
4. 避坑指南
- 文件完整性:必须包含 5 个核心文件,缺少
SEGGER_RTT_printf.c会导致格式化打印失败; - 编译器适配:
SEGGER_RTT_Syscalls_GCC.c仅适用于 GCC 编译器(MCUXpresso IDE),Keil 需替换为SEGGER_RTT_Syscalls_KEIL.c,IAR 需替换为SEGGER_RTT_Syscalls_IAR.c; - 调试口连接:确保 JLink 与开发板 SWD 接口正常连接,否则 RTT Viewer 无法识别设备;
- 缓冲区模式:裸机环境建议使用
SEGGER_RTT_MODE_NO_BLOCK_SKIP,避免缓冲区满导致 MCU 阻塞;RTOS 环境可使用SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL,通过任务调度避免阻塞; - 工具版本:JLink Software Pack 建议使用 V7.94b 及以上版本,确保兼容 RT595 芯片。
5. 进阶用法(可选)
- 日志颜色设置:通过特殊格式控制日志颜色,便于区分不同级别日志:
// 红色字体输出错误日志 SEGGER_RTT_printf(0, "x1B[31m[错误] 数据采集失败rnx1B[0m"); // 绿色字体输出正常日志 SEGGER_RTT_printf(0, "x1B[32m[正常] 系统运行稳定rnx1B[0m"); - 日志保存:RTT Viewer 支持将日志保存为 TXT 文件,点击「Logging」→「Start Logging」即可;
- 高优先级通道:配置紧急日志通道,确保关键信息不丢失:
// 通道2:紧急日志,使用更大缓冲区 uint8_t emergency_buffer[2048]; SEGGER_RTT_ConfigUpBuffer(2, "EMERGENCY", emergency_buffer, sizeof(emergency_buffer), SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
RT595 移植 JLink RTT 的核心是「文件导入 + 简单初始化」,无需修改硬件、不占用额外外设,即可实现高速日志输出。整个流程仅需 5 个核心文件,代码集成量少,适配裸机与 RTOS 环境,是串口资源紧张场景下的最优调试方案。
相比传统串口,RTT 不仅解决了资源占用问题,还大幅提升了调试效率,支持多通道、双向通信等高级功能。按照本文步骤,开发者可在 10 分钟内完成移植,快速投入调试工作。
阅读全文
198