当前位置: 首页 > 科技观察

Bootpin引发的命案

时间:2023-03-13 07:55:27 科技观察

本文转载自微信公众号《Osprey谈MCU》,作者Osprey鱼鹰。转载本文请联系Osprey谈MCU公众号。命案现场描述:程序下载到程序后,没有正常运行。怀疑是下载过程或者程序有问题,但是同样的工具,同样的程序,下载到另外一个单片机上是没有问题的。那么问题出在哪里呢?Try:遇到奇怪的问题,Osprey总是推荐直接在线调试。因为下载过程正常,说明调试器可以正常连接单片机,单片机也可以正常工作,否则调试器无法连接单片机进行下载。(通过以下界面可以查看调试器是否连接,包括调试器的产品序列号、固件版本等,右侧窗口显示连接的MCU芯片的ID信息,目前该界面没有relevantinformationbecausetherearenodebugger.)Becausedebugger如果芯片可以正常连接,那么进入在线调试模式是理所当然的。在线调试时,会发现如下窗口:(此图为群友截图,放在这里方便说明)由前面的笔记《编译优化:这些锅俺不背!》可知,本工程下载的工程应该没错,MDK也可以正常设置断点位置。但奇怪的是,程序并没有停在断点处。这是一个非常奇怪的问题。同时,这种现象也解释了程序不能正常运行的原因。由于程序没有运行到main函数,所以肯定不能正常运行。有经验的工程师应该知道,main函数并不是单片机执行的第一条指令,所以我们会怀疑是不是中断向量表有问题(第一条指令的地址存放在中断向量处)。但是根据上面,这个程序下载到其他单片机上运行正常,可以排除这个原因。那么这个问题是怎么回事呢?其实我们可以从调试截图中得到另外一个信息,单片机运行在0x1FFFxxxx地址(正常应该是0x0800xxxx)!!!并且当你单步执行的时候,你会发现汇编指令是可以执行的。同时我们可以看到汇编指令是正常的,不是全是0或者0xff,这些数据可以被解析器正确解析成汇编指令。这就说明一个问题,单片机确实在运行指令,但是我们无法通过MDK看到源码,也无法在源码层面进行调试。分析到这里,有经验的道友应该会有一些方向。在单片机中,还有哪些代码可以执行,而我们用户没有源代码?是的,就是芯片生产时固化在单片机内部的ISP程序。很多时候,当我们没有合适的调试器更新程序时,我们会选择使用串口来下载程序。而我们很清楚如何通过设置boot0引脚来完成升级,我们也知道单片机中有一段代码专门用于此,每个芯片参考手册也写了如何使用串口升级。但是我们不知道这个程序在哪里?我们不能看着这个程序执行并将我们的程序下载到微控制器。所以当我们看到问题截图的时候,并不能第一时间理解:单片机正在执行串口升级程序。(其实我们可以从参考手册中看到系统存储地址空间)至此,我们应该知道为什么单片机不能正常工作了,因为它跑错了地方!那为什么会跑到系统内存呢?肯定和开机时的bootpin电平有关。问题解决:由于定位bootpin的电平可能有问题,所以可以通过查看boot情况来确定问题。最后群友说是因为贴片放错位置了,本应该设置低电平却设置了高电平。确实,经过我的提醒,这群朋友已经定位到问题所在,但现场情况可能比那群朋友还差。比如Osprey第一次遇到这个问题时,也出现了同样的现象,但是MCUboot0时万用表检测到的电压确实偏低,但还是跑到系统存储区去执行(不是不知道这是ISP程序,而是只知道执行位置不对,等问题解决了,Osprey就知道这段代码是干什么的了)。普通人遇到这种问题可能会一头雾水,开始不断怀疑是不是自己软件的问题。但是鱼鹰不同。工作多年,经验丰富(吹牛,哈哈)。我坚信自己的判断:一定是boot0脚的问题。所以Osprey使用示波器(为什么要用示波器?要知道万用表只能检测平均电压,瞬时电平变化是万用表检测不到的),从开机观察。由于问题复现率较高,Osprey很快通过示波器的单次触发功能发现,在上电瞬间,boot0脚会突然出现高电平。进入串口下载程序也就不足为奇了。至此,作为软件工程师的职责就结束了。我们已经定位到有异常电平导致MCU工作不正常。这个时候就需要硬件工程师分析为什么会出现这个异常级别了。至于异常级别是怎么产生的,怎么解决的,不是我们软件工程师能理解的,毕竟我们不专业。总结:第一次遇到以上问题的时候,Osprey确实是一头雾水,不过通过在线调试,结合扎实的基础,解决起来并没有那么难。但是对于其他人来说,这可能是一件毫无头绪的事情,他们可能尝试了各种方法仍然一无所获。毕竟其他硬件没有问题,只是bootpin电平的问题,平时我们不会去关注。正因为如此,每次Osprey遇到这种截图,都会让他们检查bootpin。今天Osprey把这个问题记录下来,希望能让更多人知道(转发),以便更快定位问题。希望今天的笔记对你有所启发,我们下期再见!