折腾了许久,终于把 ITM 调试搞定了。首先看看效果图:
image.png
image.png
image.png
image.png
是的,你没有看错,以上所有的窗口都是由MDK支持的。这也是为什么我执着于ITM调试的原因了,因为这种调试手段实在是太方便了啊。
相信很多朋友在开发的过程中都会遇到不少的BUG,那么如何定位BUG就成了关键。早期的时候,很多人习惯用printf函数进行开发调试,我也不例外,一直以来我都是把ST-LINK当成一个下载工具。但是当我知道了ST-LINK具有在线调试功能的时候,我就再也没用过printf这种效率低下的调试方式了,或许只有在51调试的时候我才会去用吧。
关于ST-LINK在线调试技巧我会另开小节专门讲述,这一小节主要解决的就是如何利用ITM进行调试。
首先明确一点,为什么要用ITM调试?它的优势在哪里?
四线制(VCC、GND、TMS/SWDIO、TCK/SWCLK)的在线调试功能其实已经相当的强大了,它可以读取各种寄存器的值;可以在线写入读取RAM、FLASH的值;可以设置断点;也可以利用数据观察点进行数据的存取定位,极大的方便了开发者的调试。但是还有一点却是四线制在线调试方式难以实现的,那就是对于程序运行过程时的跟踪功能。如果说四线制调试是一个相对静态的调试画面,那么ITM调试就是动态的!
STM32单片机实现指令跟踪的单元有ETM,这个是专门用来进行跟踪的,性能相当强大,每一条指令的运行都可以记录下来,这样用来分析BUG相当方便。但是它有一个很大的缺点是有些STM32单片机并没有搭载这个跟踪单元,而且这个跟踪单元需要很多条线进行数据传输,所以就有了折中(我猜的)方案ITM。
这个ITM调试只比四线制多一根线(JTDO)就可以实现对指令采样跟踪,还能使用逻辑分析仪、运行时间、串口调试等功能,就是上面几张图展现出来的,相当的厉害。
现在说点ITM比较实在的问题,之前用printf函数调试的时候,一般都会将它重定向串口,这样一来,你就浪费了两个资源和增加一堆麻烦事:
1、 两个IO口
2、 一个串口
3、 除此之外,你还要安装串口模块的驱动程序,还需要一个串口调试助手
4、 有的时候可能要发送波形数据,就还需要另外一个上位机软件支持
但是用了ITM,同样的串行输入输出功能,同样的波形展示功能,只要增加一根线,r然后在开发平台上设置好,统统搞定。而且因为ITM就是专业的调试工具,也就不存在浪费ITM一说了,因为你不利用的话,这才是真正的浪费。当然了,打印功能只是其中小部分功能,更强大的是它的跟踪功能。
裸机程序运行过程其实还是比较简单的,毕竟大部分程序都是在main函数中,只有少部分代码是中断。但是系统开发就不一样了,各个任务之间的切换变成了常态,一旦出现了BUG,将比裸机开发更难定位,因为你不知道是哪些任务之间产生了干扰。但是有了ITM就不一样了,你可以利用它来监控整个运行过程,一旦出现问题,你将能很快定位出问题的代码位置。
看图感受一下任务之间的切换:
image.png
说了这么多,是不是心里已经迫不及待的想要知道如何实现呢?那就接招吧。
首先硬件上,需要一个ST-LINK(或者J-LINK,这里以ST-LINK为例进行说明),这里说明的一点就是,别用下面这种ST-LINK:
image.png
这个坑货,害我不知道走了多少弯路,就是因为它把那个关键引脚下拉接地了~ 接地了 ~~ 接地了 ~~~
导致引脚(JTDO)最终输出的波形是这样的:
image.png
看到没,电压直接下降了,导致信号识别出错。正确的电压应该是这样的:
image.png
看到Y(竖)坐标了没有,正常电压应该是非正常电压两倍还多~~~
强烈投诉卖家(虽然是公司买的,但我还是想投诉一下)。
还好当初阴差阳错的有人借走了这个ST-LINK,只能用J-LINK,然后一次就搞定ITM调试,不然我不知道要卡这里多久。
好了,牢骚说完了,进行正题,之前说了那种ST-LINK不能用,那你就别用呗,你找找其它的ST-LINK,只要这个LINK引出了VCC、GND、TMS/SWDIO、TCK/SWCLK、JTDO这5根线就可以试一试。如果你在所有正确操作后,进入Debug模式时能用示波器在引脚JTDO中得到上面正常的波形(这个波形会周期性的出现),那么硬件上就没啥问题了。学校实验室自制的ST-LINK(旁边的开发板也是实验室的作品,主控芯片STM32F103RET6)刚好少了这根线,所以只能引出这个引脚了:
image.png
现在看软件上怎么做。
打开一个STM32工程(我用的是STM32F103RET6主控芯片),选择调试器和模式:
image.png
image.png
然后开启跟踪功能(必须保证你的ST-LINK连接正常):
image.png
搞定了。是的,你没看错,全部搞定了。
网上很多资料都说需要一个.ini文件,就是下面这个:
image.png
然后是对文件内容的解释:
image.png
事实上根本不需要,为啥,因为上面的操作
image.png
就已经将这个工作做好了,在你进入Debug模式的时候MDK就会通过ST-LINK将你的配置信息写入到对应的位置,是不是相当简单啊。
好了,下面点击下面这个图标:
image.png
就可以下载程序并进入Debug模式了,然后通过:
image.png
就可以开始你的调试之旅啦(上面图片为软件仿真模式下的界面,可能和硬件仿真界面不同,自行测试)。
好好分析这几个功能,你会发现相当棒!
然后再说说如何看波形,这个我会另写一章关于逻辑分析仪的使用。
通过下面的操作,就可以将curtime这个变量添加到逻辑分析仪中观察变化的波形了。
image.png
下面是在线仿真的波形:
image.png
然后看如何最简单的输出你的数据:
image.png
就是上面的这个函数,这个函数可以在core_cm4.h中找到,如果找不到这个文件,那就试试在KEIL安装路径下找,或者网上搜,总能找到的,把相关的代码复制到你自己的源文件就行了。
这个函数相当于串口字节发送函数,只不过串口字节发送函数是通过串口传输的,这里就通过JTDO这根线传输。然后你可能需要使用printf函数打印,那么重定向即可:
image.png
然后你可能会说我还想用scanf函数,满足你:
image.png
注意这里你要申明一个变量ITM_RxBuffer(这些函数都可以通过core_cm4文件找到),用于从键盘(你没看错,就是你打字的键盘)获取用户输入的数据,然后通过下面操作:
image.png
开启你的输出窗口,看输出效果:
image.png
OK!一切搞定。
还有另一种方法观察这种数据,就是通过ST-LINK Utility软件:
image.png
然后再上一张使用J-LINK调试器的ITM指令跟踪的图:
image.png
可以发现和ST-LINK还是有些区别的。
有些朋友可能境界比较高,已经开始进行操作系统级别的开发了,那么使用这种调试手段也是相当方便的。比如你用的是KEIL官方的RTX操作系统,调试更是方便之极,看下面的图你就知道它的强大之处了:
image.png
参考链接:嵌入式OS入门笔记-以RTX为案例:十.Keil的RTX调试支持
https://blog.csdn.net/raym0ndkwan/article/details/38539237
而如果你用的是uCOS系统,也有相关的软件支持,但目前我找不到对应的资料了,如果有同学知道是哪个软件,欢迎在QQ群留言。
后期我会单独用一小节讲述另一个调试利器:数据观察点,敬请期待!
还等什么,赶紧上车吧!
最后再补习一波调试知识资料,
参考《Cortex-M3权威指南》15-16章
参考STM32中文参考手册_V10 调试接口章节
看图:
image.png
image.png
image.png
作者:EmbeddedOsprey
链接:https://www.jianshu.com/p/01855107d53e