OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 903|回复: 8

连续数据储存的轻量级磨损均衡

[复制链接]

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
发表于 2024-3-13 17:56:52 | 显示全部楼层 |阅读模式
本帖最后由 Cindre鞡 于 2024-3-25 17:47 编辑

在使用flash时,不管是mcu内部还是外置类似W25Qxx的储存器,在擦除时都会使寿命减少,在常规使用方法下(写一次数据就需读出,擦除,修改,写入),频繁的擦除操作对flash都不太友好,既然寿命是定植,那就只能减少擦除的次数,看过一些磨损均衡的方案,有的占用资源比较多,有的不太适合小flash使用,于是自己根据其原理写了一个出来。

大致思路:
1.增加一个data head,起到标记头,记录数据长度,简单验证头信息。
2.每次写入数据前,查找最后一个data head,并获取空闲地址,如没有data head,空闲地址就是0。
3.找到空闲地址后,插入data head,紧接着插入数据,然后写入flash。
4.如果当前剩余空间不足以容纳新的数据,则擦除扇区,从头写入。
5.读同步骤2,找到最后一个data head即可。

优势:占用资源少,具备flash读写即可,可以不用整个扇区读出,只需在开始位置获取第一个data head,然后根据head里记录的长度,就能获取下一个data head或者空闲地址。51单片机也能很好的使用。内外flash都可以用。支持新增数据。
劣势:data head如果与用户数据完全一样,就会冲突,后续会增加数据校验,并写入data head,会解决该问题。不支持删除数据。
后续增加多扇区磨损均衡

目前已在GD32,stc51上测试并验证。如果有好的建议我可以学习一下,优化我自己的代码。

下图是第一次写入flash的数据截图,横线是data head,两个圈是第一个数据和最后一个数据
1.png

下图是第二次写入flash的数据截图,两个横线分别代表data head,红圈为第二次写入的最后一个数据
2.png


***************************************************************
更新版本
支持多个扇区的均衡磨损,data head改为crc校验,对后边的整个数据区进行校验,即使用户数据和data head一样,也不会通过校验
下图第一横线为00 00,代表此扇区已写满,被标记为不可用状态,第二横线为data head
1.png

下图第一横线为此扇区未写满,被标记为活动状态,第二横线为data head
2.png

新增功能均在GD32,STC51上测试并验证其可行性,内存数据组织结构也是和设计一样。
接下看看如何优化性能
目前的测试时间消耗如下:
GD32F103     - W25Q16模拟总线  - 6+326 - 62ms - 跨扇区124ms @72MHz
GD32F103     - 内部Flash             - 6+326 - 32ms - 跨扇区34ms   @72MHz
STC8H8K64U - 内部Flash             - 6+14   - 32ms - 跨扇区41ms   @22.1184MHz

***************************************************************
更新版本
修改了非连续内存读写不正确的问题。

***************************************************************
更新版本
优化资源占用和性能。
目前的测试时间消耗如下:
GD32F103     - W25Q16模拟总线  - 6+326 - 7ms - 跨扇区69ms @72MHz
GD32F103     - 内部Flash             - 6+326 - 6ms - 跨扇区8ms   @72MHz
STC8H8K64U - 内部Flash             - 6+14   - 3ms - 跨扇区4ms   @22.1184MHz







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8204
金钱
8204
注册时间
2020-5-11
在线时间
3697 小时
发表于 2024-3-14 09:18:13 | 显示全部楼层
有了标记头、数据长度,那就不会与用户数据冲突啊,如同串口通信帧。
只是“查找最后一个data head”时也应按帧处理(知道了数据长度,就跳过去),不是按字节处理。
专治疑难杂症
回复 支持 反对

使用道具 举报

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
 楼主| 发表于 2024-3-14 10:52:39 | 显示全部楼层
LcwSwust 发表于 2024-3-14 09:18
有了标记头、数据长度,那就不会与用户数据冲突啊,如同串口通信帧。
只是“查找最后一个data head”时也 ...

比如data head是0xAA 0x01 0x01 0x0AC,如果用户保存的数据和这个一样就会被误认为是data head,不过我已经修改了,会对整个数据块校验,与data head的crc对比,可以排除这个误识别。
最后一个data head,是按帧处理的,跳过这个数据块,获取到空闲地址
回复 支持 反对

使用道具 举报

70

主题

6697

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12687
金钱
12687
注册时间
2012-11-26
在线时间
3710 小时
发表于 2024-3-14 14:26:13 | 显示全部楼层
这种就是需要耗时间,对减少磨损确实有益
学无止境
回复 支持 反对

使用道具 举报

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
 楼主| 发表于 2024-3-14 15:20:23 | 显示全部楼层
jermy_z 发表于 2024-3-14 14:26
这种就是需要耗时间,对减少磨损确实有益

你倒是提供了一个思路,可以优化为只在上电第一次搜索最后一个data head的位置,然后使用变量保存,之后的运行都使用该变量来确定地址,这样时间消耗主要就在上电第一次读写了,之后的读写都没有额外的时间消耗
回复 支持 反对

使用道具 举报

70

主题

6697

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12687
金钱
12687
注册时间
2012-11-26
在线时间
3710 小时
发表于 2024-3-14 17:48:07 | 显示全部楼层
Cindre鞡 发表于 2024-3-14 15:20
你倒是提供了一个思路,可以优化为只在上电第一次搜索最后一个data head的位置,然后使用变量保存,之后 ...

可以的
学无止境
回复 支持 反对

使用道具 举报

3

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
245
金钱
245
注册时间
2021-3-4
在线时间
33 小时
发表于 2024-3-20 08:51:19 | 显示全部楼层
Cindre鞡 发表于 2024-3-14 15:20
你倒是提供了一个思路,可以优化为只在上电第一次搜索最后一个data head的位置,然后使用变量保存,之后 ...

我现在的项目在用这种方法存储,还可以。
回复 支持 反对

使用道具 举报

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
 楼主| 发表于 2024-3-20 09:39:23 | 显示全部楼层
修改了一些问题
回复 支持 反对

使用道具 举报

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
 楼主| 发表于 2024-4-18 15:19:50 | 显示全部楼层
Li1069136863 发表于 2024-3-20 08:51
我现在的项目在用这种方法存储,还可以。

我的项目也在用,暂时没发现bug
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 01:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表