目录
[RTT 原理概览](#RTT 原理概览)
[RTT 的优势与局限性](#RTT 的优势与局限性)
[MCU 端集成 RTT](#MCU 端集成 RTT)
[彩色日志(ANSI 控制码)](#彩色日志(ANSI 控制码))
[RTT 实现 Shell 功能](#RTT 实现 Shell 功能)
[MCU 端轮询读取命令](#MCU 端轮询读取命令)
[Shell 工作流程](#Shell 工作流程)
在嵌入式开发中,日志输出是不可或缺的功能。传统方法如 UART、USB CDC,虽然可以满足需求,但存在占用硬件资源、传输速率受限等问题。
SEGGER RTT(Real Time Transfer) 提供了一种高效替代方案,它通过 J-Link 调试器访问 MCU 内部 RAM 来实现高速双向数据传输,不占用 UART/USB 外设。
本文将介绍:
- RTT 的原理、优劣势
- MCU 端日志打印与 Shell 功能实现
- 使用 RTT Viewer / RTT Client 的示意
- 实际项目中的注意事项
RTT 原理概览
RTT 的核心机制是通过 MCU 内部 RAM 缓冲区 + J-Link 调试器实现数据交换:
- 上行(MCU → PC):日志输出、函数返回
- 下行(PC → MCU):命令输入、控制操作
- MCU 内部缓冲区使用环形队列保证数据可靠传输
下图展示了 MCU、RTT 缓冲区和 PC 端 shell 的数据流示意:

RTT 的优势与局限性
优势
- 不占用硬件资源
- 不占用 UART 或 USB
- 无需额外 IO 接口
- 高速传输
- UART 115200bps ≈ 11KB/s
- RTT 可以达到数百 KB/s ~ MB/s
- 双向通信
- MCU 可发送日志
- PC 可下发命令,实现 Shell 功能
- 支持多通道
- 可以同时传输日志、命令、波形数据等
局限性
- 依赖调试器
- RTT 通过 J-Link SWD/JTAG 访问 RAM
- MCU 必须处于调试模式或调试会话中才能访问
- 无法在 MCU 完全脱机运行时查看日志
- 平时运行时 RTT 无法工作
- 对于长期运行日志,需要考虑 UART / USB 或 Flash 存储方案
- 命令下发依赖 PC 工具
- Shell 功能需要 RTT Client 或 RTT Viewer 作为终端
总结:RTT 更适合开发阶段调试,在项目部署阶段,仍需结合 UART/USB 做日志持久化。
MCU 端集成 RTT
必要文件
SEGGER_RTT.c/SEGGER_RTT.hSEGGER_RTT_printf.cSEGGER_RTT_Conf.h- 可选:
SEGGER_RTT_ASM_ARMv7M.S(提升性能)
来源:
- J-Link 安装目录
- SEGGER 官方 GitHub:https://github.com/SEGGERMicro/RTT
初始化示例
#include "SEGGER_RTT.h"
void RTT_Init(void)
{
SEGGER_RTT_Init(); // 初始化 RTT 缓冲区
}
调用:
int main(void)
{
HAL_Init();
RTT_Init();
SEGGER_RTT_WriteString(0, "System start\r\n");
while(1)
{
// 主循环
}
}
日志打印与彩色输出
简单打印
SEGGER_RTT_WriteString(0, "Hello RTT\n");
SEGGER_RTT_printf(0, "Value=%d\n", value);
彩色日志(ANSI 控制码)
#define RTT_RED "\033[31m"
#define RTT_GREEN "\033[32m"
#define RTT_YELLOW "\033[33m"
#define RTT_RESET "\033[0m"
SEGGER_RTT_printf(0, RTT_RED "[E] Error occurred\n" RTT_RESET);
浮点数打印处理
float temp = 25.678f;
int integer = (int)temp;
int decimal = (int)((temp - integer) * 1000);
SEGGER_RTT_printf(0, "%d.%03d\n", integer, decimal);
或封装函数:
void RTT_PrintFloat(float value, uint8_t precision)
{
int integer = (int)value;
int decimal = value >= 0 ?
(int)((value - integer) * powf(10, precision)) :
(int)((integer - value) * powf(10, precision));
SEGGER_RTT_printf(0, "%d.%0*d", integer, precision, decimal);
}
RTT 实现 Shell 功能
MCU 端轮询读取命令
char cmd_buf[64];
int len = SEGGER_RTT_Read(0, cmd_buf, sizeof(cmd_buf)-1);
if(len > 0) {
cmd_buf[len] = '\0';
ProcessCommand(cmd_buf);
}
命令解析示例
void ProcessCommand(char *cmd)
{
if(strcmp(cmd,"version")==0)
SEGGER_RTT_WriteString(0, "Version:1.0\r\n");
else if(strcmp(cmd,"reset")==0)
NVIC_SystemReset();
else
SEGGER_RTT_WriteString(0, "Unknown Command\r\n");
}
Shell 工作流程
- 用户在 PC RTT Client 输入命令
- 命令写入 RTT Down Buffer(MCU 读取)
- MCU 执行命令并通过 Up Buffer 返回日志或结果
- PC RTT Client / Viewer 显示输出
下图展示了 MCU、RTT、PC Shell 的数据流:

实际应用建议
-
开发阶段:使用 RTT 实现彩色日志 + Shell,快速调试与性能分析
-
部署阶段:结合 UART / USB 或 Flash 日志持久化,保证 MCU 脱机运行时日志可访问
-
建议通道规划:
Channel 0: MCU → PC 日志输出
Channel 1: PC → MCU 命令输入
Channel 2: 数据波形 / 高速通信(可选)
总结
SEGGER RTT:
- 高速、高效、节省硬件资源
- 支持彩色日志输出和 Shell 交互
- 支持多通道数据传输
限制:
- 依赖 J-Link 调试模式
- 脱机运行日志查看仍需其他方案
结合 DWT、RTT 和多通道 Shell,STM32开发者可以搭建完整的 日志 + Shell + 性能分析调试体系,大幅提升调试效率与可视化能力。