微控制器C程序关闭DEBUG后while循环等待interrupt handler无法退出问题
问题根因
1. 核心触发原因:缺少volatile关键字导致编译器优化异常
你定义的两个全局变量call_irq_handler、call_irq_handler_previous会在中断上下文被修改,但没有加volatile修饰符。C编译器在非DEBUG模式下默认会开启优化,此时编译器分析主程序的while循环逻辑时,发现循环内部没有修改这两个变量的代码,就会直接优化掉循环条件中每次对变量的内存读取操作:只会在第一次进入循环前读取一次两个变量的值存到寄存器中,后续循环判断时直接复用寄存器里的旧值,哪怕中断里已经修改了内存中变量的实际值,主程序也感知不到,就会永远卡在循环里。
2. DEBUG模式正常的原因
DEBUG模式下循环内会调用printf函数,printf属于标准库外部函数,编译器无法判定该函数会不会修改这两个全局变量,因此不会做变量读取的优化,每次循环判断条件都会重新从内存中读取两个变量的最新值,中断修改后就能正常触发条件不成立,退出循环。
修复方案
给两个被中断修改的全局变量加上volatile修饰,强制编译器每次访问变量时都直接从内存读取,不做寄存器缓存的优化:
// 修改变量定义,添加volatile修饰 volatile uint8_t call_irq_handler = 0; volatile uint8_t call_irq_handler_previous = 0;
如果你的MCU带有数据缓存,还需要额外保证这两个变量所在的内存区域不被缓存,或者在读取变量前做缓存失效操作,避免缓存和内存数据不一致。
内容的提问来源于stack exchange,提问作者Dooraim
相关产品推荐
相关产品推荐

