项目中为了保证数据可靠写入EEPROM,写操作后执行读数据,再与写数据进行比较。促发我的一些思考 .... 关于合理管理嵌入式系统中的EEPROM器件的寿命与可靠方法。
设备上电后从eeprom中获取系统参数,在内存中保留一份系统参数的数据结构映射。currend threads 直接从内存中获取,不需要从eeprom中再次获取从而增加系统开销。currend threads 只需专注处理业务逻辑,设立eeprom_manage_threads管理内存中系统参数同步到eeprom,通过 currend threads 向 eeprom_manage_threads 发送消息即可,currend threads 不参与管理系统参数的可靠写入。
需要说明的是,为了数据及时同步到eeprom,我的设想是提高 eeprom_manage_threads 优先级,好处是 currend threads 发送消息后 OS 即刻发生上下文切换,调度 eeprom_manage_threads 完成数据同步。 当然,这样的设计同样存在缺陷,例如 currend threads 每次同步数据时,都会发生一次上下文切换,考虑到某些数据不要求即刻同步,带来的后果是额外增加系统开销。
为了灵活处理上面的问题,我的设想是在消息队列里增加 priority 元素管理 eeprom_manage_threads 是否立即同步。
通过 priority 把消息划分为两个级别:at_once 和 period 。
at_once :OS 即刻发生上下文切换,调度 eeprom_manage_threads 执行数据同步
period : 允许滞后写入, eeprom_manage_threads 等待 OS 调度后再执行数据同步
显然,当消息队列属性是 at_once 时,需要采用临时提高 eeprom_manage_threads 优先级的方法,触发 OS 即刻发生上下文切换,保证数据及时同步到eeprom。其他时候就等待 OS 调度与 currend threads 同优先级或次优先级的 eeprom_manage_threads ,假设系统设定线程时间片大小 10ms 和线程数 20 来计算,耗时是200ms 以内(排除外部事件)。
未完待续........
补充:period模式在被调度执行时查询map表,每个eeprom数据结构中的元素对应1bit的更新标志,当标志为1的时候,则执行对应元素的写入操作和保证可靠写入操作;当然也可以增加1个标志用于完整数据结构全部写入eeprom,这需要我们自己思考;最后是思考异步事件-断电发生时,可能存在数据未更新到eeprom 以及 正在写入数据时被打断。有一个简单的测试方法是 定时发送数据给到设备,设备拿到数据后执行写入eeprom 或者 等待调度时再写入,我们不定时的频繁开关电源,观察它每次上电从设备中读出的真实数据与断电前发送的数据是否一致?
经过思考开关电源引起的eeprom数据未更新或被打断更新导致数据错误问题,似乎只能从检测电压降低时,立即去执行写入更新操作,假如此时有一个电容能提供这个写入更新的时间,那就完美解决这个问题;如果没有这套监测电压和电容放电机制,似乎每个系统都存在写入数据时被打断的可能。
下面是从网络查找提炼的一些方法,试图增加读写可靠性和擦写次数:
a. 把数据以有意义的数据块作分类管理,在数据的块的头、位加固定标识和CS/CRC校验 模式;
b. 为增强实际的可靠性,在需要写入的时候,可以在写入后,再读出来进行数据的比对,确认写入是否正确;或者在需要读出的时候,读两次、或者多次,检查每次的数据是否一致;
c. 对于出现异常的数据,最好有容错机制,可以回到默认状态值,不至于系统此时因为某个参数改变的崩溃;
d. 将数据整理好,以数据块的方式存储,一组数据分10个块地址存储,每次写完后转移到下一块写,即10次写操作中每个物理的数据存储地址只操作了1次;
e. 采取反码冗余备份校验的方式,需要存储的数据按照原码和反码存两份,需要读取时分别读取原码和反码,进行校验,若校验不通过,则根据一定的算法恢复数据或者采取缺省值;
网友评论