【故障现象】
1. BCM工位诊断TCU无响应。
2. 部分板子MCU冷(-35°~-10°)启动失效,未开狗一直起不来,开了狗会复位,常温启动之后降温,板子正常运行。
3. 部分板子MCU常温启动也失效,未开狗一直起不来,开了狗会复位。
4. 更换SPI FLASH,常温及-35°故障消失,同时焊接原外部FLASH的板子常温故障仍在。
5. 读FLASH(内部的和外部的)前添加延时,故障消失。
6. 冷启动失效的板子,温度回升,故障消失。
7. 修改OSTick计数模式,故障消失。
【故障原因】
1. 硬件(SPI flash)的特性有差异(随硬件或者随温度),导致了软件的启动时序 有差异。
2. 在操作MCU的FDL库时,被意外中断产生未定义错误 ,导致MCU跑飞。
【解决办法】
1. 执行临界代码前,保留程序状态字(PSW),禁止中断。
#define Irq_Save(flags) flags = _Irq_Disable_save()
#define Irq_Restore(flags) _Irq_Disable_restore(flags)
static inline unsigned long get_psw( void )
{
uint32 psw;
asm volatile(" stsr PSW,%[psw]":[psw] "=r" (psw ) );
return psw;
}
static inline unsigned long _Irq_Disable_save(void)
{
unsigned long result = get_psw();
Irq_Disable();
return result;
}
2.执行完临界代码,恢复PSW,恢复中断。
static inline void _Irq_Disable_restore(unsigned long flags) {
/* restore PSW */
asm volatile(" ldsr %0,PSW" : : "r" (flags) );
}
【分析过程】
- 挂接调试器,发现PC指向0x100C0,为MAE异常。
datasheet:
2. 调试器提示code Flash访问失败。
3. 分析任务栈,提取出异常时的函数调用栈(需要从汇编角度对函数的出栈入栈数据分析)。
据此定位系统最后一次执行的函数为R_FDL_FCUFct_initRAM()。
4. 将问题点怀疑到FDL相关操作上。
执行FDL库时,不允许访问CODE FLASH.
5. 查看FDL操作code。
综上,执行FDL库时,没有添加临界段互斥操作,这样在操作FDL库时,可能被ISR或者调度器打断。