之前在stm32f103上编写了在线升级的功能,一直运行好好的,在使用过程中,突然发现几台设备无法正常进行跳转了,于是对这个问题进行了定位。最后发现中断影响到了程序的跳转以及正常运行。
该设备实现的功能比较简单,就是不停获取adx453陀螺仪的数据,然后通过串口上传数据,同时另外一个串口用于打印信息。一个是rs232接口,一个是rs485接口。
把定位情况如下显示:
指示是否正常工作的led长亮,显示程序没有正常运行起来。针对第二种问题进行了问题定位及分析,最后发现为RS485芯片有几率会损坏,导致rs485接口上一直有中断数据接收,导致卡死在了中断里,代码中进行了修复规避。
现把分析过程记录下来,以方便以后追踪以及积累调试经验。
针对adx453的led长亮,通过添加打印信息,发现iap跳转地址都是ok的,但是似乎没有跳转到app里去。如果是必现的,那肯定是代码问题,这个不是必现,就相对比较难定位问题。当时也没怀疑到中断问题上去。
通过app的debug,发现进不了主循环,然后一步步走,发现有时候会卡死在printf打印函数里,这个就非常奇怪了,简单的打印函数没有什么地方可以卡死的。多次debug下,有几率进入到主循环,发现多次卡死在了串口接收程序中去,这时候才联想到最早调试的时候一直没有rs485打印输出,最后发现是那片485芯片有问题,这里如果一直进入中断函数的话,最有可能也是这个rs485出问题了。最后把关于rs485(所用的是usart2)的初始化以及中断接收函数都屏蔽掉,发现led灯可以正常 ,程序可以正常运行了。
此外把MCU烧回原来的程序,把有问题的设备上的RS485芯片焊下来,mcu程序能正常运行,也验证了是RS485芯片的问题。
问题找到了,但因为这种现象不是很常见,以前用的是rs485接口进行imu数据交互,因在现场出现有些设备的阻抗不匹配的问题,后来就不使用rs485,改用rs232(usart1)进行imu数据的交互,此时如果直接屏蔽掉rs485功能,也是可以的,但是以后万一出现了其他问题,没有串口打印,而是直接debug的话,有可能会破坏现象(debug会重新烧写程序到mcu里),且之前做的app在线升级功能,也是通过rs485升级。最后考虑了一下,采用代码规避的方式来规避这个问题。通过使用宏定义的方式,默认是rs485打开的,一旦以后出现led长亮的现象,怀疑是rs485芯片可能坏掉了,通过放开下面的宏定义来进行测试。
进行修改后的代码功能验证,因陀螺仪设备时好时坏的问题,验证不是很顺利。把修改的代码直接烧进去,发现不管是否放开rs485功能,led都能正常闪烁,最后在最初的代码基础上,一步步修改代码,找到了最终的问题所在,也验证了新修改代码的功能性。起初led长亮的现象:使用的是uart1(rs232)进行串口打印信息,此时rs485上一直有中断数据输入,就一直卡在了while循环接收函数里,跳不出来了,导致led一直长亮,也没有imu数据输出;
修改后的代码,使用usart2(rs485)输出打印信息,因为rs485是半双工,在进行发送的时候,会置高PA.8管脚,发送数据结束后,再置低PA.8管脚,此时就导致没有中断数据输入,可以跳出上面的while接收函数,从而导致又能再次进行主循环,让led闪烁。
相对来说,修改后的代码,即使rs485损坏了,或者一直有中断数据接收,mcu程序也能正常运行。算是能规避rs485损坏的问题,但是以后如果rs485输入调试指令,不响应的话,也可往rs485芯片是否损坏这方面考虑。
相关文章: