STM32输出调试信息的两种方式

来源:漫长当下 嵌入式 18 次阅读
摘要:今天讲讲STM32输出调试信息的两种方式吧,只要是写程序那就几乎避免不了要打印调试信息,在单片机开发的时候我们打印调试信息普遍都是使用串口,但是随着软硬件的不断更新,现在我们可以使用更加方便的工具和方式来打印调试信息。        目前大家学习和使用比较广泛的单片机可能就是STM32了,那就以STM32和Keil MDK环境为例吧,理论上是只要支持使用J-Link下载程序的芯片都能够使用此方法来

今天讲讲STM32输出调试信息的两种方式吧,只要是写程序那就几乎避免不了要打印调试信息,在单片机开发的时候我们打印调试信息普遍都是使用串口,但是随着软硬件的不断更新,现在我们可以使用更加方便的工具和方式来打印调试信息。

       目前大家学习和使用比较广泛的单片机可能就是STM32了,那就以STM32和Keil MDK环境为例吧,理论上是只要支持使用J-Link下载程序的芯片都能够使用此方法来打印调试信息,在上一篇文章中讲解了J-Link驱动的下载及其安装后的一些上位机,里面提到了J-Link RTT Viewer这个软件,也就是今天我们要介绍的除了串口之外的另一种打印调试信息的工具和方式。

       下面这张表是一张关于串口和J-Link RTT Viewer的粗略对比:

优点 缺点
串口 1、可以重定向到printf,可输出的内容格式非常多 1、速度较慢2、 需要占用单片机额外的串口资源3、不适合在中断中调用4、使用操作系统时需要进行保护
J-Link RTT Viewer 1、速度较快2、只需要连接上J-Link开启上位机就可看到打印信息3、可在中断和有操作系统的场景中调用 1、不能输出中文及浮点数,输出格式相对有限

串口这种方式相信大家都使用过了,就不进行讲解了,这里主要讲解J-LinkRTT Viewer这种方式的使用,下图1是J-Link驱动安装目录的的内容:

图1

这里的I盘是我安装的盘符,如果你的安装路径不一致,以你的安装路径为准,可看到里面有一个RTT目录,打开目录后里面有一个.zip压缩包,这个压缩包就是我们所要关注的内容,将其解压后有以下文件(这里我使用的J-Link驱动版本为6.44,可能有版本区别,不要死心眼,但是版本最好要新一点的,推荐6.40),见图2:

图2

其中Examples是使用示例,Syscalls是平台相关的内容要不要都可以,另外两个.txt可以粗略看一下,我们将RTT目录整个复制到工程文件中,如下图3:

图3

然后使用KeilMDK打开工程,并且将RTT目录路径添加到工程中,见图4:

图4

添加好路径后,我们就可以使用SEGGER_RTT_printf();函数(可在SEGGER_RTT.h头文件中找到声明)来输出调试信息了,其函数原型为:

intSEGGER_RTT_printf(unsignedBufferIndex, constchar * sFormat, ...);

第一个参数为数据输出到哪个通道,在J-LinkRTT Viewer软件中可得知最多16个通道可用,其取值范围为0~15;第二个参数就是数据以什么格式输出;第三个参数为可变长参数;其实和printf();函数的区别就是多了一个通道号,一般使用通道0便可满足需求了,比如打印”helloword”,首先包含头文件#include “SEGGER_RTT.h”到相应的.c文件中,然后使用下面的语句输出就行了。

SEGGER_RTT_printf(0,”%s\r\n”,”helloword”);

一切准备就绪就可以连上J-Link编译下载程序使用J-LinkRTT Viewer查看调试信息了,打开J-LinkRTT Viewer软件后,会先弹出下面图5,需要选择连接方式和芯片型号,一般除了特殊用法,只需要选择好芯片型号就OK了,如果J-Link连接正常,在图6窗口就可以看到你打印的内容了。

图5

图6

J-LinkRTTViewer这个软件还有其它好用的功能,你可以在J-Link驱动安装目录的Doc目录找到相关文档了解其更详细的用法。

在实际的工程使用中,我们可以使用宏定义进一步封装SEGGER_RTT_printf();这个函数,这样我们就可对调试信息进行输出控制了,这样也省去了每次还要多填一个通道号参数,代码如下。

#ifndef __APP_COM_H#define __APP_COM_H
/***************************************************************/      /*用于控制输出调试信息*/#define PRINTF_DEBUG  1U#if (PRINTF_DEBUG > 0U)    #include "SEGGER_RTT.h"    #define   PRINTF_Dbg(...)                                                       \                    do{                                                             \                        SEGGER_RTT_printf(0,"file:%s,line:%d,",__FILE__,__LINE__);  \                        SEGGER_RTT_printf(0,__VA_ARGS__);                           \                      }while(0)
    #define   PRINTF(...)                                                           \                      SEGGER_RTT_printf(0,__VA_ARGS__)                    #else  #define   PRINTF_Dbg(...)  #define    PRINTF(...)#endif/***************************************************************/
#endif/*__APP_COM_H*/
评论区

登录后即可参与讨论

立即登录