【嵌入式实战】不用串口!SEGGER RTT高速无侵入打印输出
来源: | 作者:风标电子工程师 | 发布时间: 2026-10-13 | 6 次浏览 | 🔊 点击朗读正文 ❚❚ ▶ | 分享到:
点击蓝字 关注我们

嵌入式调试时,很多工程师习惯用串口做日志打印。但串口调试存在不少痛点:需要占用 UART 引脚、波特率受限,高频打印会干扰 MCU 实时运行;硬件没有预留串口时,还需要额外飞线,调试很不方便。

SEGGER RTT(Real‑Time Transfer,实时传输),借助 J‑Link 调试接口实现双向调试输入输出,不需要占用硬件串口引脚、不干扰 MCU 实时性,传输速率远高于传统 UART 串口,裸机、RTOS 项目都可以直接使用,也是 SystemView 工具的数据传输底层基础。


01
一、RTT 核心特点

• ✅ 无需额外硬件引脚:复用 SWD/JTAG 调试接口,不用 UART,不用飞线

• ✅ 几乎无侵入:后台内存读取,不打断程序运行,不影响实时性

• ✅ 高速传输,传输速率最高可达 MB/s 级别,远快于串口

• ✅ 双向通信:既可以 MCU 输出日志到 PC,PC 也可以下发命令给 MCU

• ✅ 多通道能力:支持多路独立通道,日志、错误信息、性能数据分开传输

• ✅ 跨平台:Windows /macOS/ Linux 都支持,适配 Cortex‑M、RX 系列内核芯片

支持全部 J‑Link、J‑Trace 调试器,无型号门槛,普通 J‑Link Base 就可以使用 RTT。

02
二、RTT 基本工作原理

RTT 核心是 MCU 内存里开辟的环形缓冲区。

1. 固件代码调用 RTT API,把日志数据写入芯片内存的上行缓冲区;

2. J‑Link 调试器通过调试接口后台读取内存,不需要暂停 MCU 程序;

3. PC 端 RTT‑Viewer 接收数据,展示日志;

4. 下行通道反之,PC 下发数据写入下行缓冲区,MCU 读取执行命令。

关键点:芯片必须支持调试器后台内存访问,绝大多数 Cortex‑M 内核 MCU 都原生支持。

通道概念

• 通道 0:默认终端通道,日常打印日志都使用通道 0;

• 可以自定义多个上行 / 下行通道:比如通道 1 专门传输性能统计数据,通道 2 做命令交互;

• 单通道还支持最多 16 个虚拟终端,实现多窗口日志分类输出。

03
三、软硬件环境要求

软件

• J‑Link 软件安装包(自带 RTT‑Viewer,免费)

• IDE:SEGGER Embedded Studio / Keil MDK / IAR 均可

硬件

• 任意型号 J‑Link / J‑Trace 调试器

• Cortex‑M 或 RX 内核目标 MCU

04
四、快速上手移植步骤

1、添加 RTT 源码到工程

需要把 SEGGER RTT 源码加入项目,核心文件:

• SEGGER_RTT.c 主逻辑

• SEGGER_RTT.h 头文件

• SEGGER_RTT_Conf.h RTT 配置文件,可修改缓冲区大小

• SEGGER_RTT_printf.c 提供格式化打印 API

Keil 环境如需重定向 printf,加入SEGGER_RTT_Syscalls_KEIL.c。

2、简单示例代码

c

#include "SEGGER_RTT.h"

int main(void)

{

// RTT初始化

SEGGER_RTT_Init();

while(1)

{

// 字符串输出,效率更高,推荐优先使用

SEGGER_RTT_WriteString(0, "Hello RTT!rn");

// 格式化打印,类似printf

SEGGER_RTT_printf(0, "Counter = %drn", cnt++);

HAL_Delay(500);

}

}

SEGGER_RTT_WriteString性能优于SEGGER_RTT_printf,高频打印场景优先选用。

3、PC 端打开 J‑Link RTT‑Viewer

RTT‑Viewer 包含在 J‑Link 软件包中,无需单独下载,两种工作模式:

1. 独立模式(Stand‑alone):Viewer 自己连接 J‑Link,不需要 IDE 开启调试会话;

2. 附加模式 Existing Session:依附 IDE 已经打开的调试会话,共用 J‑Link 连接,推荐调试时使用此模式。

配置要点

1. 选择芯片型号,调试接口选择 SWD;

2. RTT 控制块默认勾选Auto Detection自动识别;

3. 点击 OK 即可,程序运行就能看到日志输出。

05
五、RTT 高级用法

1、多通道配置

可以配置不同通道做不同用途,示例:

c

//通道1,用于性能追踪,缓冲区满则阻塞,保证数据不丢失

SEGGER_RTT_ConfigUpBuffer(1, "TRACE", NULL, 1024, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);

//通道2,普通日志,缓冲区满直接丢弃,不阻塞业务流程

SEGGER_RTT_ConfigUpBuffer(2, "APP_LOG", NULL, 1024, SEGGER_RTT_MODE_NO_BLOCK_SKIP);

两种缓冲模式:

• SEGGER_RTT_MODE_NO_BLOCK_SKIP:非阻塞,缓冲区满丢弃新数据,不能卡住业务循环,普通日志首选;

• SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL:缓冲区满时阻塞写操作,适合关键事件,会占用 MCU 运行时间。

2、虚拟终端与彩色打印

同一个物理通道可以开启多个虚拟终端窗口,区分普通日志、警告、报错;


支持 ANSI 颜色控制码,输出彩色日志,方便区分日志级别。

3、配套工具

• J‑Link RTT‑Viewer:GUI 图形终端,日常调试首选;

• J‑Link RTT Client:命令行工具,适合自动化脚本;

• J‑Link RTT Logger:直接把 RTT 日志保存本地文件,用于自动化测试记录日志。

本系列上一篇 Ozone 自动化测试脚本,同样支持读取 RTT 数据,实现自动化日志采集。

06
六、最佳实践与避坑指南

1. 中断里面慎用 SEGGER_RTT_printf,格式化消耗 CPU 时间;中断中尽量用SEGGER_RTT_WriteString短字符串输出,或者把数据丢队列交给主循环打印。

2. 缓冲区大小在SEGGER_RTT_Conf.h调整;高频日志场景,适当调大缓冲区,避免丢日志。

3. RTT‑Viewer 搜不到 RTT 控制块:

○ 确认固件已经执行SEGGER_RTT_Init();

○ 芯片型号选择正确;

○ 如果优化等级较高,部分编译器会把 RTT 控制块优化掉,可以加__attribute__((used))修饰。

4. 不要在产品正式发布固件保留 RTT,仅用于调试阶段。

07
七、方案总结

RTT 是 SEGGER 工具链非常实用的调试功能:

1. 硬件条件受限、没有多余串口引脚时,直接替代串口调试打印;

2. 高实时性项目,相比串口打印,不会干扰业务时序;

3. 支持多通道、日志落盘,可以和 Ozone 自动化测试、SystemView 系统分析联动使用;

4. 上手简单,几乎所有使用 J‑Link 的嵌入式项目都可以快速接入。

下一篇预告:RTOS 调试神器 SystemView,看清任务切换、中断抢占,定位系统卡顿根源。

END