不知道你是否有这样的经历,测试的机器运行半个月、一个月的都没啥问题,突然就死机了,或者运行错误了,总之莫名其妙。但是此时,你的调试器已经从机器上拔下来了,无法在线调试观察死机后的现场了,你无法观察到你的变量、寄存器、外设、堆、栈等处于什么情况,这个时候你不得不重新接上调试器,再次运行程序以等待问题的出现。这个笨方法存在几个问题:第一、因为复现率太低,所以你的电脑必须一直连接电脑,否则问题出现了无法确认。第二,万一中途因为各种原因(线拔了,KEIL 意外退出了)导致调试器和机器的连接出现了问题,那么只能重来了。第三,可能运行几个月都不会再出问题,但是你却知道,这里隐藏了一个炸弹,指不定什么时候就爆了;更有甚者,可能连接调试器后这个问题可能就没有了,但是断开之后就又有问题了。
针对以上问题,我们就会想,是否存在一种方法,能够在出现问题之后,可以使用调试器抓获现场环境呢?我们都知道,KEIL 环境下,连接调试器后,单片机进入调试模式时,KEIL 会自动将整个单片机进行复位(可能是内核复位,也可能是系统复位,也可能是 RST 引脚复位),复位操作对于刚下载的程序而言,可以很方便的帮助开发者更方便的进入调试环境,但是对于机器的问题现场而言,这是在破获现场!但是根据以往的认知,我们总是以为进入调试模式时,必然需要先进行单片机复位的,所以我们对这种难复现的 BUG 总是感到无能为力。
今天,鱼鹰教大家一个方法,如何使用 KEIL 调试器抓获 STM32 的 BUG 现场(其他单片机可自行测试),这个方法将颠覆你的认知,可以在单片机运行时进入调试模式,从而抓获现场!这个功能其实在某一个软件是集成了的(不记得哪一个软件了),但在 KEIL 中我们需要几步操作完成。
1、新建一个工程目标(可命名为 NotRest):
这样你可以看到你现在的目标:
接下来的所有操作都在这个目标进行。事实上,如果只是为了抓获 BUG 现场,是不需要新建目标的,但是为了今后可以方便的不复位单片机也能进入调试模式,也为了不改变以前目标的配置,增加一个目标还是很有必要的,这样,你可以根据需要(是否复位芯片)切换目标了。
2、新建一个 load.ini 文件,文件内容如下:LOAD %L INCREMENTAL 该文件用于加载 axf 文件到 KEIL 中,但是不会下载到单片机中,而 axf 文件可以方便我们进行源码级别的调试。
3、打开该目标的 option 进行配置:
4、点击仿真按钮,记住了,别点下载按钮(鱼鹰非常不喜欢别人先点下载按钮再点仿真按钮,因为刚编译后的代码,如果你直接点仿真按钮,在默认配置下会自动下载和进入调试模式的,比较方便)。
注意,一定要确定该目标可以正常使用(即不会复位单片机)才能真正用于实际的 BUG 现场,不要没有做测试就直接拿它去调试实际的单片机,否则可能因为没有正确配置,而破坏了现场环境(默认配置下,会直接复位单片机)!