1. 从安装目录下找到RTT源代码
C:\Program Files\SEGGER\JLink\Samples\RTT
将压缩包解压,解压后目录如下
将RTT中源代码拷贝至项目工程中
2. 修改配置和源代码
SEGGER_RTT_Config.h 中可根据需要裁剪内存占用大小,和是否启动LOCK和UNLOCK, 并添加浮点数支持的宏定义
//! 浮点数的支持(需要420 BYTE的flash空间) #ifndef SEGGER_RTT_PRINT_FLOAT_ENABLE #define SEGGER_RTT_PRINT_FLOAT_ENABLE (1) #endif
如何支持浮点数打印,修改SEGGER_RTT_printf.c
调用关系SEGGER_RTT_printf–>SEGGER_RTT_vprintf, 固在SEGGER_RTT_vprintf中添加如下代码
int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { char c; SEGGER_RTT_PRINTF_DESC BufferDesc; int v; unsigned NumDigits; unsigned FormatFlags; unsigned FieldWidth; char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; BufferDesc.pBuffer = acBuffer; BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; BufferDesc.Cnt = 0u; BufferDesc.RTTBufferIndex = BufferIndex; BufferDesc.ReturnValue = 0; do { c = *sFormat; sFormat++; if (c == 0u) { break; } if (c == '%') { // // Filter out flags // FormatFlags = 0u; v = 1; do { c = *sFormat; switch (c) { case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; default: v = 0; break; } } while (v); // // filter out field with // FieldWidth = 0u; do { c = *sFormat; if ((c < '0') || (c > '9')) { break; } sFormat++; FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); } while (1); // // Filter out precision (number of digits to display) // NumDigits = 0u; c = *sFormat; if (c == '.') { sFormat++; do { c = *sFormat; if ((c < '0') || (c > '9')) { break; } sFormat++; NumDigits = NumDigits * 10u + ((unsigned)c - '0'); } while (1); } // // Filter out length modifier // c = *sFormat; do { if ((c == 'l') || (c == 'h')) { sFormat++; c = *sFormat; } else { break; } } while (1); // // Handle specifiers // switch (c) { ... //! ============================================================ //! 支持浮点数 #if (SEGGER_RTT_PRINT_FLOAT_ENABLE != 0) case 'f': case 'F': { float fv; fv = (float)va_arg(*pParamList, double); //取出输入的浮点数值 if(fv < 0) _StoreChar(&BufferDesc, '-'); // 判断正负,用来显示负号 v = abs((int)fv); //取整数部分 _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); //显示整数 _StoreChar(&BufferDesc, '.'); //显示小数点 v = abs((int)(fv * 1000)); v = v % 1000; _PrintInt(&BufferDesc, v, 10u, 3, FieldWidth, FormatFlags); //显示小数点后三位 } break; #endif //! ============================================================ default: break; } sFormat++; } else { _StoreChar(&BufferDesc, c); } } while (BufferDesc.ReturnValue >= 0); ... }
3. 用户层封装, 在头文件中实现如下代码
//! 调试输出配置
#define RTT_DBG_ENABLE (1)
#if RTT_DBG_ENABLE
#include "SEGGER_RTT.h"
/* 初始化调试模块 */
#define DEBUG_INIT() SEGGER_RTT_Init()
/* RTT 终端号 */
#define RTT_DBG_PORT 0
#define LOG_PROTO(type,color,format,...) \
SEGGER_RTT_printf(RTT_DBG_PORT,"%s%s"format"\r\n%s", \
color, \
type, \
##__VA_ARGS__, \
RTT_CTRL_RESET)
/* 清屏*/
#define log_clear() SEGGER_RTT_WriteString(RTT_DBG_PORT, " "RTT_CTRL_CLEAR)
/* 无颜色日志输出 */
#define log_debug(format,...) LOG_PROTO("D:","",format,##__VA_ARGS__)
/* 有颜色格式日志输出 */
#define log_info(format,...) LOG_PROTO("I:", RTT_CTRL_TEXT_BRIGHT_GREEN , format, ##__VA_ARGS__)
#define log_warn(format,...) LOG_PROTO("W:", RTT_CTRL_TEXT_BRIGHT_YELLOW, format, ##__VA_ARGS__)
#define log_error(format,...) LOG_PROTO("E:", RTT_CTRL_TEXT_BRIGHT_RED , format, ##__VA_ARGS__)
#else
#define DEBUG_INIT()
#define log_clear()
#define log_debug
#define log_info
#define log_warn
#define log_error
#endif
4. 测试
这样浮点数打印以及日志颜色都能使用了,注意:浮点数只能打印两位,如需要更多则修改源码即可
20221114修改:之前打印-0.03
之类小于0的小数,负号会丢失,固重新修改了下打印浮点机制,现已正常
参考链接1:用VS Code开发STM32(四)——增加SEGGER RTT日志输出支持
参考链接2:给SEGGER RTT的 SEGGER_RTT_printf() 函数添加浮点显示功能
补充:
- 移植到rt1052上遇到的问题和解决
a. 移植到rt1052上后发现显示不出来,然后网上搜到了这个文章:https://blog.youkuaiyun.com/qq_31860135/article/details/128135539
b. 然后从map文件中找到了segger_rtt.o的.bss端地址(即rtt上传至rtt viewer工具的缓冲数组)
c. 然后修改rtt viewer工具配置
d. 最终正常的显示效果
2. 问题分析
a. 尝试使用了6.98e版本的rtt viewer,发现可以自动检测到,直接显示(无需手动设置地址)
b. 对比两个版本设置差异:
c. 最终发现7.88e版本找不到具体的型号了,只有系列类型;而6.98e还可已找到对应的型号,所有6.98e可以直接自动检测,而7.88e需要手动输入地址