I.问题现象、
2022年5月13日,接开发人员反馈,某仪表代码存在读取bug,当读取日,月冻结电度索引时,会导致频繁复位。也即发送01 03 29 00 00 01 CRCH,CRCL。报文时,仪表会产生复位现象。
经检查,仪表A会产生日冻结,月冻结,最值冻结数据错乱现象,仪表B 会导致复位现象。
II.问题分析
一、故障复现:
发送报文:
报文正常应答。报文发送过后,日冻结,月冻结,最值冻结数据错误,EEPROM上电读取错误次数错误。 其余数据正常。如下:日,月冻结。
最值日冻结
最值月冻结
运行参数:
软件复位后:除了记录产生过错误,其他数据均正常。
错误次数不再增加,日月冻结及最值冻结数据恢复。
二、故障分析:
1、查看代码,发现代码存在范围越界bug,如下:
修改如下:
2、代码修改及举一反三。
修改如下:(2700 2900 均修改。)
3、仿真验证
修改前:
发生溢出后,接口调用EEPROM读取指针为空。实际未读取,默认应答发送缓冲内数据,也即上次数据。
不发生错误,实际数据应该如下:
相关存储内存大小为124字。static WORD16 sg_awComBuf[124];
发生错误后,内存地址从2DA0开始,自2EC6地址溢出,发生错误。总计126字,溢出。最大地址到2FA2
查看MAP文件,查到相关地址分配为
sg_ptComReg 0x10002f88 0xe0 Data Lc modbus.o [1]
sg_ptDevList 0x10002e98 0xf0 Data Lc Interface.o [1]
sg_awComBuf 0x10002da0 0xf8 Data Lc modbus.o [1]
正是接口文件溢出地址。
实际被错误改写的接口地址只有EEPROM。如下所示:
正常的分配如下图:
sg_ptDevList 数据被覆盖后,无法恢复。只能复位/重启 进行恢复。
继续排查,上述数据被修改后,发生EEPROM存储也会一致失败,跟故障情况相符。
综上,数据只是显示错误,实际并未错误,设计上重要的数据存在FRAM中,EEPROM仅用作重要数据备份以及一些不重要的数据存储。
相关数据如下:
发生异常后,上述数据无法正常读写。
修改后:
验证功能正常。
III.解决措施
临时措施:
1、改bug实际使用中不会发生,测试存在bug,已出货产品,库存品均不处理。
永久措施
1、代码修改,试流,变更。
IV.总结建议
执行减操作时,需要避免溢出情况的发生。