1. 为什么你的Bootloader跳转FreeRTOS总是死机?
我遇到过太多工程师在STM32上实现Bootloader跳转FreeRTOS时遇到各种诡异问题。明明代码看起来没问题,但一跳转就HardFault,或者系统直接卡死。这其实不是你的代码写得不好,而是有几个关键细节被忽略了。
最让人头疼的是,这些问题在裸机程序跳转时可能不会出现,但一旦加入FreeRTOS,情况就完全不一样了。根本原因在于FreeRTOS改变了处理器的运行模式和使用的中断,而Bootloader跳转时如果没有正确处理这些变化,就会导致系统崩溃。
我记得第一次实现这个功能时,花了整整两天时间调试。跳转后系统随机性死机,有时候能正常运行几分钟,有时候刚跳转就挂掉。最后发现是堆栈指针没有正确初始化,导致任务切换时访问了非法内存地址。
2. 中断处理:跳转前后的关键操作
2.1 为什么必须关闭所有中断
在Bootloader跳转到应用程序之前,关闭所有中断是必须的操作。这不是建议,而是强制要求。原因很简单:如果跳转时还有中断处于活跃状态,这些中断会尝试在应用程序中寻找中断服务函数,但此时应用程序的中断向量表还没有正确设置,结果就是直接进入HardFault。
我通常使用以下代码关闭中断:
// 关闭所有中断
__disable_irq();
// 特别关闭SysTick中断
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
这里有个细节需要注意:仅仅使用__disable_irq()是不够的,因为SysTick定时器可能还在运行。FreeRTOS使用SysTick作为系统时钟源,如果不在跳转前彻底关闭它,跳转后就会出问题。
2.2 中断向量表重定位
这是最容易出错的地方之一。FreeRTOS应用程序有自己的中断向量表,通常不在默认的0x08000000地址。如果你没有在应用程序中正确设置向量表偏移寄存器(VTOR),那么所有中断都会指向错误的位置。
在应用程序的main函数开始处,一定要添加这行代码:
// 设置中断向量表偏移
SCB->VTOR = FLASH_BASE | 0x8000; // 假设应用程序从0x08008000开始
我建议在系统初始化代码的最开始就执行这个操作,越早越好。我曾经遇到过因为VTOR设置得太晚,系统初始化过程中发生中断导致死机的情况。
3. 堆栈指针:MSP与PSP的模式切换
3.1 理解两种堆栈指针的区别
Cortex-M内核有两个堆栈指针:主堆栈指针(MSP)和进程堆栈指针(PSP)。裸机程序通常只使用


968

被折叠的 条评论
为什么被折叠?



