发现问题
项目开发过程中,中断中要计算几个浮点数,仿真时发现浮点数经常性计算错误:计算结果不可能是负值,但却会计算出负值,而且与真实结果完全没有关联性.当时单片机使用的是STM32F429ZGT6,主频设置为192MHz,运行RTOS,开了十个定时器中断.以及几个外部中断
可能的原因
- 因为执行的函数是在中断中,而且这个函数还挺长,两三百行,所以想到是有可能进中断次数太多,导致栈溢出.将栈调大至0x1000即4K,还是不行,遂排查栈的问题.
- 设置的主频过高,导致单片机稳定性降低,因F429推荐主频是180M,我设置的是192M.将主频设置为180M后再次仿真仍然会出现这个问题,所以也不是超频的原因
- 片子有问题,虽说概率极低,但仍有可能.但是更换了好几块板子,仍然有问题,排除此原因.
- 芯片FPU配置有问题.但将FPU关掉后仍然会出现这个问题,遂排除
发现端倪
因为我设置一个数组,十个定时器中断每次运行此函数时都会将数组中对应的元素加一,然后在执行完成后减一,所以数组中的元素值同一时间只有可能有一个为1,但是仿真的时候却发现有的元素是非零值,甚至有的元素大于1,发现临界段中的代码也会被中断中止,原以为进入临界段会关闭总中断,但查看代码后发现,并没有关闭总中断操作,所以,问题应该是计算浮点数过程中,触发中断,然后可能是浮点数未能正常入栈,导致返回来继续执行时从栈中取出来的浮点数时乱码,从而导致偶发性计算错误.
解决方法
在需要计算浮点数的语句前面关闭总中断,计算完成后再开启总中断.这里使用keil独有的操作总中断函数__enable_irq()
和__disable_irq()
.加上这两句后,问题没有再出现过.