问题描述
在调试程序透传功能时发现,使用J-Link下载程序后功能正常。拔掉J-Link,电源供电,APP端无法收到数据,功能异常。使用J-Link进入仿真模式运行,则功能又恢复正常。
主芯片:STM32F103RC
RTOS:RT-Thread
定位过程
- 刚开始怀疑电源供电,主芯片程序没有运行。从主芯片与电池之间的串口交互看,主芯片确实没有转发出指令。
增加了一个闪灯线程,电源供电下,灯没有闪烁。怀疑硬件电源部分问题,但验证硬件的流水灯程序可以正常运行,仍然从软件查找。 - 使用点亮LED的方式查找,逐渐调整点亮的位置,最终发现是启动main线程后运行出错。
- 熟悉了下程序,打开程序的
RT_USING_CONSOLE
宏,通过J-Link RTT Viewer V7.52d查看log。电源供电时,程序进入了hard_fault。但实际刚上电时已经出错,rt_system_heap_init
设置线程堆栈时,结束地址比起始地址还小:
可以看出因为线程堆栈异常,导致main线程一启动就错误了。mem init, error begin address 0x20001a18, and end address 0x20000000
- 继续查找,发现是HAL_GetDEVID返回0导致。
问题解决
- 怀疑是电源不稳定,在上电初始化之前增加大概3S延时- -无效。
- 重复读取,每次读取中间增加延时- -无效。
- 继续测试,发现上电后,使用J-Link RTT Viewer V7.52d连接。此时硬复位,即可恢复正常。推测与J-Link有关。
- 查看手册《STM32_MANUAL_CN》:
- 看起来没什么问题。更改关键字
DBGMCU_IDCODE
搜索,最终发现只能在调试模式下访问, 不能通过用户软件操作。对应下载了勘误手册:
这也对应解释了第3条的现象。
总结
这样看来,此芯片不能通过HAL_GetDEVID来获取ID,然后得到芯片资源空间。解决问题占用了较多时间,一直想尽快定位解决,以后需要注意:
- 调试前熟悉当前的程序框架,一些实现机制。
- 适当更换关键字
- 官方手册使用,勘误手册第一次用到。