故障现象:
生产中,发现一块电能表出一个很大的值。
故障分析:
1、排除存储问题, 未发现存储异常。
2、排除堆栈,数组溢出可能。
3、再电能处理过程中,使用了SOC芯片给出的寄存器操作,如下:
if((EmuRead(EPR_Power_P))>0x800000)
EPR_Power_P该寄存器值再中断中也有使用。
在查看SOC芯片说明,Emu读取再SOC芯片内部通过总线读取的, 可能存在重入。
不仅如此,基本所有SOC外设都存在重入可能。
解决方法:
1、脉冲中断中取消读寄存器,使用变量sMEAS.sP2进行判断,防止重入:
//if((EmuRead(EPR_Power_P))>0x800000)
if(sMEAS.sP2 < 0) // 取消读寄存器避免可重入问题。) 2、取消计量模块出错时初始化次数的限制:
if(EmuErr > 10) //取消恢复的次数限制,直至恢复成功
3、掉电存储电能脉冲,防止电能脉冲丢失:
sFlagState.uFRAM |= (1<<FILE_ENERGY); //掉电时储存电能脉冲
总结建议:
再排查函数重入问题是,我们不仅需要分析函数本身是否可重入, 对于SOC芯片, 我们还需要判断外设本身是否公用总线,有无可能重入。(主要是判断中断里面有操作的函数)