I.问题现象、

2022年5月13日,接开发人员反馈,某仪表代码存在读取bug,当读取日,月冻结电度索引时,会导致频繁复位。也即发送01 03 29 00 00 01 CRCH,CRCL。报文时,仪表会产生复位现象。
经检查,仪表A会产生日冻结,月冻结,最值冻结数据错乱现象,仪表B 会导致复位现象。

II.问题分析

一、故障复现:

发送报文:

ES召回 like_Data

报文正常应答。报文发送过后,日冻结,月冻结,最值冻结数据错误,EEPROM上电读取错误次数错误。 其余数据正常。如下:日,月冻结。

ES召回 like_Data_02


最值日冻结

ES召回 like_ES召回 like_03

最值月冻结

ES召回 like_重启_04


运行参数:

ES召回 like_Data_05


软件复位后:除了记录产生过错误,其他数据均正常。

错误次数不再增加,日月冻结及最值冻结数据恢复。

ES召回 like_Data_06


ES召回 like_网络_07


ES召回 like_Data_08


ES召回 like_数据_09


二、故障分析:

1、查看代码,发现代码存在范围越界bug,如下:

ES召回 like_网络_10


修改如下:

ES召回 like_Data_11


2、代码修改及举一反三。

ES召回 like_网络_12


修改如下:(2700 2900 均修改。)

ES召回 like_重启_13


3、仿真验证

修改前:

发生溢出后,接口调用EEPROM读取指针为空。实际未读取,默认应答发送缓冲内数据,也即上次数据。

ES召回 like_数据_14


不发生错误,实际数据应该如下:

ES召回 like_ES召回 like_15


相关存储内存大小为124字。static WORD16 sg_awComBuf[124];

发生错误后,内存地址从2DA0开始,自2EC6地址溢出,发生错误。总计126字,溢出。最大地址到2FA2

ES召回 like_重启_16


查看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]

正是接口文件溢出地址。

ES召回 like_重启_17


实际被错误改写的接口地址只有EEPROM。如下所示:

ES召回 like_ES召回 like_18


正常的分配如下图:

ES召回 like_Data_19


sg_ptDevList 数据被覆盖后,无法恢复。只能复位/重启 进行恢复。

继续排查,上述数据被修改后,发生EEPROM存储也会一致失败,跟故障情况相符。综上,数据只是显示错误,实际并未错误,设计上重要的数据存在FRAM中,EEPROM仅用作重要数据备份以及一些不重要的数据存储。

相关数据如下:

ES召回 like_ES召回 like_20


发生异常后,上述数据无法正常读写。

修改后:
验证功能正常。

III.解决措施

临时措施:
1、改bug实际使用中不会发生,测试存在bug,已出货产品,库存品均不处理。

永久措施

1、代码修改,试流,变更。

IV.总结建议

执行减操作时,需要避免溢出情况的发生。