嵌入式 printf的几种办法 (ITM、SWO、semihosting、Keil Debug Viewer、RTT、串口重定向printf)
嵌入式/单片机printf的几种办法:
关键词:
ITM、SWO、semihosting、Keil Debug Viewer、RTT、串口重定向printf。
名词释义
ITM: https://blog.csdn.net/hanchaoman/article/details.
SWO: https://blog.csdn.net/weixin_30407613/article/details.
semihosting:半主机模式 https://blog.csdn.net/yhneng/article/details/6299893.
需要注意的是,我并没有学会半主机模式,该方式似乎是对调试器有特殊要求,JLINK不能实现,并且ARM后面又推出了ITM机制,所以下文不再讲述半主机的printf方式
Keil Debug Viewer : https://blog.csdn.net/yhneng/article/details/6299893.
参考博客(大牛)
https://blog.csdn.net/ybhuangfugui/article/details/94378013
打印的几种方式printf
1.软件仿真打印输出
2.串口UART打印输出
3.SWO打印输出
4.JLink-RTT打印输出
printf方式 | 优点 | 缺点 |
---|---|---|
软件仿真printf | 无须硬件 | 很多项目不能运行 |
串口打印 | 适用于正式运行产品、无须调试器 | 串口打印耗时,影响MCU的实时性 |
SWO打印 | 不影响MCU的实时性 | 必须使用仿真器 |
RTT打印 | 不影响MCU的实时性 | 必须使用JLINK |
来看一下实时性的对比图:
打印82个字符
RTT仅耗时1us
SWO耗时120us(速率设置为1500Khz)
半主机模式耗时10.7ms
串口打印耗时约1ms(波特率115200情况下)
在实时性上,RTT > SWO >串口 >半主机模式
1软件仿真printf
何为软件仿真printf? 就是只在集成开发环境中模拟printf仿真输出,不需要连接开发板(硬件MCU)即可实现。
这种方法非常不推荐,因为软件仿真与真实环境有很大的差异,很多工程代码,在软件仿真的时候根本跑不了。就会出现卡在某个地方不动的尴尬情况(软件仿真的时候会有绿色的方框,如下图)
如果你不清楚,可以参照,以下所有的博客都是指的软件仿真:
软件仿真https://blog.csdn.net/ybhuangfugui/article/details/94378195?
半主机模式的软件仿真https://blog.csdn.net/zhc335134701/article/details/81261070?
keil软件仿真https://blog.csdn.net/weixin_45380951/article/details/103372085?.
没错,基本上博客写明Use Simulator ,并修改Dialog DLL的情况都是软件仿真。
2串口重定向printf
这种方式有非常多的博客可以参考,例如:
串口重定向博客1https://blog.csdn.net/qq_39101111/article/details
串口重定向博客2https://blog.csdn.net/zouleideboke/article/details
串口重定向博客3https://blog.csdn.net/qq_22329595/article/details
该方式比较简单,不再重复论述。
3SWO打印输出printf
3.1名词释义
先看此博客使用SWO代替UART,实现Printf打印功能https://blog.csdn.net/qq_37663138/article/details
再稍微解释一下:
1 在Cortex-M3\M4\M7系列MCU中,内核的调试组件有一个仪器跟踪宏单元(ITM) 。请注意如果你的芯片是 Cortex-M0 或者其他ARM内核,不支持ITM
什么是ITM请看这里https://blog.csdn.net/leekay123/article/details
3.2硬件接线
我们都知道SWD接口正常使用是四根线。而使用ITM需要多使用到SWD一根线:SWO.
先找一找JLINK接口定义SWO的位置:
再找出你的原理图上,SWO的管脚位置:(我的项目此处使用stm32f407ze)
查清楚以后,用杜邦线连接板子上PB3 和JLINK的13脚。
3.3软件配置
3.3.1SWO管脚配置
注意需要配置PB3为SWO. 如果是使用stm32cube mx, 可以直接按下图使能即可。
如果是其他芯片或者自己使用标准库,则需要编写代码,确保管脚配置正确。
3.3.2重定向代码添加
可以新建一个.c文件,也可以放在任何一个现有.c文件中。
#include "stdio.h"
#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA 0x01000000
struct __FILE { int handle; /* Add whatever needed */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f) {
if (DEMCR & TRCENA) {
while (ITM_Port32(0) == 0);
ITM_Port8(0) = ch;
}
return(ch);
}
3.3.3使用keil查看、设置
1 使用微库
2 使能debug setting- trace
3.3.3使用JLINK-SWO Viewer查看、设置
下面是使用J-Link SWO Viewer 查看的,这种方式可以不进入debug模式。每次产品上电后都需要退出软件,并重新选择器件和频率。
3.4查看效果
需要说明以下几点:
Core Clock一定要保持与主频,也就是系统时钟频率一致。如果不一致后面没有任何输出。
默认ITM是端口0,一共可以使用32个端口,如果想使用其他端口,需要修改重定向代码内容,例如使用端口8
int fputc(int ch, FILE *f) {
if (DEMCR & TRCENA) {
while (ITM_Port32(8) == 0);
ITM_Port8(8) = ch;
}
我这里是移植了LWIP代码,需要打开LWIP的打印使能。
下面是用keil Debug Viewer里面查看的,由于keil软件的限制,必须要进入debug 模式,才能打开Debug Viewer窗口
查看效果
3.5 SWO的其他功能
用SWO测量代码运行时间https://blog.csdn.net/weixin_34004576/article/details
4Link-RTT打印输出
这个功能只是进行了初步使用,没有非常详细使用,打算放到后面专门讲RTT。
如果只是想使用RTT打印功能,可以参考如下内容
https://blog.csdn.net/gyb510/article/details
https://blog.csdn.net/ybhuangfugui/article/details
5总结
本文讲述了打印Printf的四种方式,并着重讲述了如何用SWO的方式将信息打印出来.四种方式没有完全绝对的优劣,可以根据实际情况进行选择。
希望本文对读者有帮助,记得点个赞哦。