前言
在进行单片机开发的过程中,不可避免的要用到日志打印来辅助进行开发及问题排查。肯定有聪明的小伙伴会说了,直接用下面这种方法把printf重新向到串口不就得了:
int fputc(int ch, FILE *f)
{
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart2, temp, 1, 2);
}
在串口资源不是特别紧张的情况下,使用这种方法当然没问题,但是如果单片机的串口资源全部都被占用了,又有串口调试的需求,那就需要一些特殊的技巧了。
RTT的全称是实时传输(Real Time Transmit),是Segger公司推出的,搭配Jlink使用的调试手段,与其它的日志打印手段相比,其具备下列特点:
方式 | 物理接口 | 优点 | 缺点 |
---|---|---|---|
RTT | SWDIO+SWCLK | 速度非常快、不占用额外接口 | 需要移植RTT库 |
EventRecoder | SWDIO+SWCLK | 不占用额外接口 | 依赖MDK等开发环境,看日志需进debug |
串口 | TX+RX | 无需专用上位机、重定向fputc简单 | 速度较RTT慢、需要占用串口 |
SWO | SWDIO+SWCLK+SWO | 不占用串口、重定向fputc简单 | 需要额外的SWO引脚、简单的下载器都没有带 |
RTT连接拓扑如下图所示:
有眼尖的小伙伴看到了,虽然SEGGER RTT官方说是搭配Jlink的调试手段,但是没说别的调试器就一定不能用🙃
既然有这么个东西,我又碰巧有个Jlink,那不如试试看好不好用😀
驱动移植
第一步、下载Jlink驱动
甭管你有没有Jlink,SEGGER RTT是Jlink驱动里面的功能,驱动还是要下的:
访问SEGGER的官网,在Jlink的下载页进行下载即可:https://www.segger.com/downloads/jlink/
第二步、提取单片机上的RTT库
打开Jlink驱动的安装位置(默认为:C:\Program Files\SEGGER\JLink),不知道的话就右键打开文件位置去找
然后在这个目录下找到RTT的库文件:
解压后我们会用到压缩包里面的这两个文件夹:
第三步、移植RTT库
把RTT文件夹、Config文件夹里面的SEGGER_RTT_Conf.h放到项目里面去,这些文件都放进去
注意:我这边是把SEGGER_RTT_Conf.h跟其它的.h放一起了,你可以像官方的例程一样建个Config放
然后MDK里面该加的文件都添加进去:
include文件夹也别忘了
如果你的SEGGER_RTT_Conf.h放的目录跟我一样的话,你应该还有修改下这个地方
现在你就可以用如下的代码就行打印的测试了:
void SEGGER_RTT_Test(void)
{
SEGGER_RTT_Init(); //初始化只需在单片机运行开始时调用一次即可
uint32_t cycle = 1000;
while (cycle--)
{
SEGGER_RTT_printf(0, "0123456789abcdefgh\r\n");
}
}
第四步、封装RTT库接口(可选)
毕竟是拿来打日志的,直接调用printf那样不太优雅,新建个CAT_LOG.h文件,把下面的内容放进去:
/*
* @Author: xmprocat
* @Date: 2023-03-20 20:26:22
* @LastEditors: xmprocat
* @LastEditTime: 2023-03-20 20:26:42
* @Description:
*/
#ifndef _LOG_H_
#define _LOH_H_
#include "SEGGER_RTT.h"
#define LOG_DEBUG 1
#if LOG_DEBUG
#define LOG_PROTO(type,color,format,...) \
SEGGER_RTT_printf(0," %s%s"format"\r\n%s", \
color, \
type, \
##__VA_ARGS__, \
RTT_CTRL_RESET)
/* 清屏*/
#define LOG_CLEAR() SEGGER_RTT_WriteString(0, " "RTT_CTRL_CLEAR)
/* 无颜色日志输出 */
#define LOG(format,...) LOG_PROTO("","",format,##__VA_ARGS__)
/* 有颜色格式日志输出 */
#define LOGI(format,...) LOG_PROTO("I: ", RTT_CTRL_TEXT_BRIGHT_GREEN , format, ##__VA_ARGS__)
#define LOGW(format,...) LOG_PROTO("W: ", RTT_CTRL_TEXT_BRIGHT_YELLOW, format, ##__VA_ARGS__)
#define LOGE(format,...) LOG_PROTO("E: ", RTT_CTRL_TEXT_BRIGHT_RED , format, ##__VA_ARGS__)
#else
#define LOG_CLEAR()
#define LOG
#define LOGI
#define LOGW
#define LOGE
#endif
#endif // !_LOG_H_
用的时候先include “CAT_LOG.h”,然后这样用:
通过不同的日志等级还可以有不同的颜色显示,这里先放个效果:
到这里,单片机上需要的工作就结束了,只需要接上Jlink,用USB进行连接就行了。
有JLINK
如果有Jlink,可以直接使用J-Link RTT Viewer、J-Link RTT Logger、J-Link RTT Client进行日志查看。就拿最简单的J-Link RTT Viewer举例子,在开始菜单或者是搜索框找到它:
默认情况下只需设置需要调试的芯片跟调试器接口即可,可以参照下图:
设置好点击OK就可以开始愉快的看日志了(SEGGER_RTT_printf函数的第一个参数就是指定在哪个Terminal窗口显示,默认是0):
无JLINK
买一个Jlink最简单😅…
既然是要白嫖,那使用体验肯定是没那么好的,但是要用还是可以用的。本方法也可以搭配Jlink使用,但是不推荐。
第一步:装个Python
步骤自行百度,只要是Python3.6以上就行
第二步:安装pyocd
python3 -m pip install -U pyocd
第三步:安装芯片的pack
这里以Stm32F103ZET6为例子,装这个pack
python3 -m pyocd pack -i stm32f103
第四步:查看设备列表
python -m pyocd list
我这边是插了两个下崽器所以有两个设备
第五步:连接设备
python -m pyocd rtt
总结
SEGGER RTT毕竟是设计来与Jlink配合进行使用的,日志传输的速度非常快,并且支持在裸机、RTOS环境下运行,下图是官方宣传的理论性能:
虽然支持与DAP等非Jlink调试器一起使用,但是与之配合的pyocd只在最新版本支持RTT,虽然RTT本身并不支持中文,但是时不时会因为字符编码格式问题抽风,使用体验算不上好(J-Link RTT Viewer不会出现)。
作为一种不占用串口的日志输出方式,在部分应用场景下还是值得一试的。文章来源:https://www.toymoban.com/news/detail-755145.html
参考文献
https://www.segger.com/downloads/jlink/
https://www.segger.com/jlink-rtt.html
https://zhuanlan.zhihu.com/p/163771273?utm_id=0文章来源地址https://www.toymoban.com/news/detail-755145.html
到了这里,关于【单片机】使用SEGGER RTT实现日志打印的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!