做过IAP升级的开发者几乎都遇到过这个场景:向量表偏移反复确认,SCB->VTOR也写对了,APP单独烧录到起始地址跑得稳稳当当,可Bootloader一跳转,程序立刻飞掉。问题往往不在向量表本身,而是跳转流程里藏着几个容易被忽略的细节。

1. 跳转前没关全局中断
Bootloader运行期间可能开了串口、定时器等中断。跳转时如果PRIMASK没置1,刚跳进APP的瞬间,一个悬起的中断触发,而此时APP的向量表还没完全接管,CPU直接跑飞进HardFault。跳转前执行__disable_irq()是必选动作。
2. 中断挂起标志没清干净
光关中断不够。外设中断标志可能已经挂起,跳转后APP一旦开中断,挂起的请求立刻响应,但中断服务函数入口地址还是错的。跳转前必须逐个清除所有已使能外设的中断挂起位。
3. 堆栈指针没重新加载
跳转函数里第一件事是设置新的MSP值。APP向量表第一个字就是初始堆栈指针,必须用这个值更新MSP。如果漏掉这一步,APP运行时堆栈可能指向错误区域,函数调用几次就栈溢出崩溃。
4. APP的SystemInit覆盖了VTOR
很多标准库的SystemInit函数会重新把VTOR设回默认值0x0000。你在main函数第一行辛辛苦苦设的偏移,被启动代码里的SystemInit悄悄覆盖了。正确做法是修改system_xxx.c里的VECT_TAB_OFFSET宏,从源头解决。
5. 跳转前没反初始化关键外设
Bootloader里用过的DMA、SDRAM控制器等外设,跳转前最好执行DeInit。这些外设的寄存器状态与APP初始化预期不一致,可能导致APP在启动阶段就卡死。
6. 链接脚本里的起始地址没改
Keil的Target选项里改了ROM起始地址,但分散加载文件里还是从0x08000000开始。链接器把你的代码放到了错误的位置,跳转过去自然找不到正确的指令。
此文内容来自兆亿微波北京,如涉及作品内容、版权和其它问题,请于联系工作人员,我们将在第一时间和您对接删除处理!

扫码关注












































