【STM32】内部Flash掉电数据处理策略

版权声明:本文为CSDN博主「简一商业」的原创文章,我只是在原来文章的基础上增加了一些个人的理解,方便以后回顾,如有侵权请联系我进行删除。
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liwei16611/article/details/88764968

1、原因

由于FLASH的擦除和写入的特性,如果在擦除中掉电或者写入时掉电或者复位(以下简称为掉电),有可能会出现失败的情况,下次再上电读取就会出错。

擦除的时候掉电:不能保证擦除完全,但是已经擦除的部分,肯定是0xFF了。

写入的时候掉电:已经写入的就是正确的,电平掉到最低极限工作电压附近时,写入的就无法保证了,地址无法保证,写入的值也无法保证。没有写到的,肯定还是 0xFF,因为写之前肯定是进行擦除的。

2、解决方式

2.1、软件方式解决思路

1)要改写某扇区内容,先把该扇区内容备份到一个特殊的扇区; 
2)在某个地方写一个特殊的标记; 
3)完成该扇区的改写操作,清除标记; 
4)系统每次上电或复位,都去检查下标记,就跟windows下的“磁盘扫描程序”一样,即使最坏情况,也可以恢复改写之前的数据。

这个过程“备份->置标记->写->清标记”的办法,是个可行的办法,也是目前比较通行的办法。

示例:

如下图所示:

在这里插入图片描述

具体实现方式和基本思想是这样的,使用两个sector互为备份,首先判断valid,如果数据都有效,比较version看谁的数据比较新,使用最新的数据。我们来分析下一下几种情况的处理逻辑。

正常的情况下:

1)初始化,sector 0和sector 1的valid值都为0xff,使用sector 0擦写,version为0,valid为0x5a。

2)第二次擦写,sector 0的valid为0x5a,sector 1的valid为0xff,表明sector 1为无效数据,使用sector 1擦写,vesion在上次的基础上加1,valid为0x5a。

3)第三次擦写,sector 0和sector 1的valid值都为0x5a,比较version,sector 1的version比sector 0大,所以使用sector 0擦写,sector 1为备份数据,version加1,valid为0x5a。 (总是使用旧数据扇区进行擦写操作)

4)依此类推,擦写数据的过程中,version高的为最新数据,version低的为备份数据。

掉电的情况下:

1)如果在擦除sector 0的过程发生掉电,前半部分数据为0xff,后半部分数据是旧数据;重启后比较valid都为0x5a,进而比较version,因为最新数据的version没有写进去,所以sector 1的versoin较高,使用sector 1的旧数据。(擦除过程发生掉电)

2)如果在擦完sector 0的时刻掉电,所有数据都为0xff;重启后sector 1的valid为0x5a,使用sector 1的旧数据。 (擦除完成的时刻发生掉电)

3)如果在写sector 0的时刻掉电,前半部分数据为新数据,后半部分数据为0xff;重启后sector 1的valid为0x5a,使用sector 1的旧数据。(写过程发生掉电)

相对网络上搜索到的掉电备份方法(写备份区-备份标志-写目标区-清备份标志),优点是每次修改数据只需要擦写一次,速度较快;缺点是存储一个sector的数据需要两个sector的空间。

注意:

这只能保证数据能恢复到之前的状态,不能确保数据结构的完整性。

譬如你有一个数据结构有16字节(它们之间是有逻辑关系的),跨两个扇区保存,现在要全面更新这16个字节的数据,如果发生某个扇区没有成功更新(即恢复到之前的数据),就会发生新旧数据同时存在的情况,程序利用这些数据来操作,就有可能发生错误。

所以,还需进一步的机制来保证“整体数据结构”的完整性,譬如某个文件的一部分数据坏掉了,那么就把整个文件无效掉。

2.2、具体实现过程(数据读取操作)

在这里插入图片描述

2.2、具体实现过程(数据写入操作)

在这里插入图片描述

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值