STM32L433经Bootloader启动后首次定时器中断触发程序停止
异常根因
- 核心问题是跳转应用时未重定位Cortex-M内核的向量表偏移寄存器(VTOR):STM32上电后默认将起始地址为0x08000000的Bootloader Flash映射到内核向量表寻址空间,TIM7中断触发时,内核会从当前VTOR指向的Bootloader向量表中查找中断服务函数入口,但Bootloader中没有定义对应TIM7的中断处理逻辑,要么直接进入死循环,要么取到非法地址触发HardFault,导致第一次中断触发后系统就停止运行。
- 直接将应用烧录到0x08000000地址运行时,默认VTOR值0刚好匹配应用向量表位置,因此不会出现该问题。
- 次要隐患是Bootloader跳转前未清理中断状态,若后续Bootloader新增外设/中断逻辑,残留的中断挂起位可能在VTOR重定位完成前触发异常。
修复步骤
- 应用侧添加VTOR配置
在应用main函数中获取到Cortex-M外设实例后、所有外设和中断初始化前,添加VTOR寄存器配置,地址与应用Flash起始地址完全一致:
// 注意这行必须放在所有外设初始化、中断开启操作之前 cortex_peripherals.SCB.vtor.write(0x08010000);
说明:STM32L433的向量表总大小为256字节,配置的0x08010000地址满足VTOR的256字节对齐要求,无需额外调整偏移。
- Bootloader侧添加跳转前状态清理
在Bootloader调用跳转函数前,添加全局中断关闭、NVIC中断挂起位清理逻辑,避免跳转过程中误触发中断:
// 放在unsafe { cortex_m::asm::bootload(vt); } 之前执行 unsafe { // 关闭全局中断 cortex_m::interrupt::disable(); // 清除NVIC所有中断使能和挂起标志 let nvic = &*cortex_m::peripheral::NVIC::PTR; nvic.icer[0].write(0xFFFFFFFF); nvic.icer[1].write(0xFFFFFFFF); nvic.icpr[0].write(0xFFFFFFFF); nvic.icpr[1].write(0xFFFFFFFF); }
验证逻辑
修改后完整启动流程为:
- Bootloader完成应用存在性校验
- 关闭全局中断、清理所有残留中断状态
- 跳转至应用入口
- 应用启动第一时间将VTOR指向自身向量表起始地址
- 后续初始化定时器、开启中断后,所有中断触发时内核都会正确从应用向量表中查找对应服务函数,TIM7中断可正常持续触发,计数逻辑运行正常。
内容的提问来源于stack exchange,提问作者Robert.H
相关产品推荐
相关产品推荐

