起因
手头一个项目对于成本要求颇高,所以选择了一款意法半导体的STM8L152。STM32市占率非常高,STM8来之其早前的ST7内核发展而来,处于对于该公司的充分信赖,毕竟这应该是比较成熟的内核了。结果踩了一个大大的深坑。
现象
常见的串口收发中使用环形缓冲器,会用到临界区保护。而脉冲计数等也是如此,ISR计数器加一,需要主循环中临界保护,保存到EEPROM中,然后重置计数器。而大多数的临界区保护通过关闭全局中断使能来实现。偏偏在STM8L中撞鬼了。
在EXTI外部中断使能的脉冲计数中,会导致程序跑飞,而去掉了临界区保护,程序恢复正常。
追踪下来发现:RIM/SIM语句重置了中断优先级,且在同一个ISR中反复嵌套,只压栈不退栈,直接堆栈爆掉,程序跑飞。
在内部EEPROM初始化中关闭全局中断避免不可预测后果,这也是常见的做法。但是如果使用中断闭合,会导致外部中断变量不是增加一而是增加一个固定常数。
追踪下来发现:而关闭开放中断会重置中断,外部中断被定时中断嵌套后,而STM8L中所谓的虚拟寄存器没有压栈处理,直接被TIM4 ISR占用,导致虚拟寄存器指向外部中断的服务程序被改写。
ErrSheet
在STM8相对应的错误报告中,的确将ITC部分的Bug列为“没有解决方案,也没有解决计划”的严重错误。
在STM8L上别使用RIM/SIM语句,即便要用也需要关闭对应IT_CONFIG,如果是EXTI中断,则自求多福。比较建议使用STM32L0XX,或者其他家的Cortex-M0+内核处理器,其实MSP430也可以用。
望周知,别踩坑。