来源:公众号【鱼鹰谈单片机】,ID :emOsprey
一个学员项目上需要完成app升级功能,但是跳转后直接 hardfault,项目紧急,只能找上鱼鹰加急处理(课程福利)。
这种问题我都是比较自信的,M0+ 内核,感觉问题不大,只是没想到学员公司保密性比较强,不能远程控制电脑,只能微信视频进行指导调试,折腾许久,才最终定位跳转地址出现问题。
static uint32_t jmp_app;
static uint32_t jmp_stack;
jmp_app = xx
jmp_stack = xxx
关闭中断
__ISB();
__DMB();
设置中断向量表
设置 msp 和 psp 栈
((void (*)(void))jmp_app)();
代码类似如上,但是很奇怪的是,执行最后一条代码时,会从栈中取jmp_app的值(通过汇编分析),导致最终跳转地址异常而hardfault,这个变量明明是静态全局变量,而且同样的代码在stm32没有问题。
全局变量数据从栈里面取,怎么都不符合常理,要么优化后从寄存器取,要么从ram中取才对,没听说过要通过栈取数据(难道是前面设置栈的操作导致?)。
这个问题最终由学员发现是编译器的锅,用-O0 compiler6可以稳定出错,compile5没问题,之前看一篇硬汉的文章说ac6在O0处理复杂宏时会产生大量的栈,O1没问题,才知道编译器也不可尽信,汇编也需要懂,否则出现类似问题根本无法解决,不知道各位道友是否有遇到类似问题。