论武天地论坛

 找回密码
 立即注册
搜索
查看: 15762|回复: 0

17-单片机stm32的flash保存数据优化方案(让擦写次数达到上百...

[复制链接]

58

主题

58

帖子

244

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
244
发表于 2020-9-21 10:14:37 | 显示全部楼层 |阅读模式



说明
此套方案是刚刚给别人做的项目的一个存储方案,因为很实用,几乎大家都用的到,所以分享给大家使用!
制作原因:
我项目上使用的STM32的Flash存储的数据,STM32的Flash可以反复擦写1万次左右,
由于项目上需要反复的操作Flash,一个小时就需要操作一次,如果每次都擦写,
这样算下来一年就擦写了 8760次,也就可以用 10000/8760 = 1.1年左右就坏掉了.
解决方案思想
1.首先大家需要知道,凡是数据是0xFF的地址,不需要再次擦除就可以写入.
假设一页1024字节,先全部擦除了
由于上面说的特性,可以这样做,
第一次写一个数据到Flash的0地址
第二次写一个数据到Flash的1地址
第三次写一个数据到Flash的2地址
每次写的时候就不需要擦除!

2.其实如果想真正的应用其实是下面这样子
准备好几页Flash,准备一个固定大小的数组,把数据放到数组里面
然后把数组里面的数据拷贝进第一页的最前面,然后再更新数组里面的数据
再把数组的数据拷贝到第一页后面没有使用的地方,然后就是循环
如果第一页不能拷贝了,就把数据拷贝到第二页,然后擦除第一页
如果第二页不能使用了,就把数据拷贝到第三页,然后擦除第二页
如果第三页不能使用了,就把数据拷贝到第四页,然后擦除第三页
如果第四页不能使用了,就把数据拷贝到第一页,然后擦除第四页
然后就是循环
假设数组是20个数据,Flash的每一页最大存储是510个数据
那么每页Flash擦除一次以后可以使用 510/20 = 25次
如果Flash的擦写次数是10000次,那么当前的方式可以使用
25*4*10000 = 100万次
当然如果还嫌小,可以多加几页,如果用10页
25*10*10000 = 250万次
也可以减小数组大小,如果只存2个数据
510/2*4*10000 = 1020万次
819239-20200905051341226-1887843828.png




源码使用
1.需要这两个文件
用户把以下两个文件移植到自己的工程即可使用!
819239-20200905061744003-206829490.png




2.存储数据
1.请用户自行修改Flash的大小和存储数据的页地址
819239-20200905165905051-973509227.png



2.默认最大存储20个数据(u16型),第一个和最后一个不可用,最大存储18个数据
请用户根据自己的需求修改!
819239-20200905062554896-1696642796.png




3.把数据存储到Flash
819239-20200905062659053-839894242.png



4.关于存储的数据
用户把数据放到了数组  flash_helper_struct.FlashHelperData[1]  的位置
其它地方需要这个数据,只需要获取上面数组里面的数据即可!
如果用户需要查看Flash里面的数据,用户需要在调用完刷新以后调用
FlashHelperGetIndex(1);//1是索引,要和上面数组的下标保持一致.
819239-20200905063627166-391604803.png



819239-20200905063714266-2100673949.png




3.设备重启以后获取先前存入的数据
1.在初始化存储函数后面直接用索引获取即可!
819239-20200905063856817-2074466960.png



819239-20200905064048493-1393574407.png




简要概括
1.实际上存数据就是把数据写到
flash_helper_struct.FlashHelperData 数组
然后调用  FlashHelperUpdate();函数刷新一下即可!
注意:
flash_helper_struct.FlashHelperData[0] //第一位
和 flash_helper_struct.FlashHelperData[19]  //最后一位
我作为了数据开头和结尾标识,用户不能使用

用户可以用 FlashHelperGetIndex函数获取刚刚写入的数据
用来判断是不是写入成功.
如果写入不成功可以再次调用 FlashHelperUpdate();函数
然后再调用 FlashHelperGetIndex函数获取刚刚写入的数据


扩展
代码是先写入再判断擦除,一是保证确实写进去,二是为了下面的问题.
假设写入数据的时候突然断电了
用户可以在断电中断函数里面重新设置一下数组的值
然后调用一下刷新函数!
注意:供电电池不一样,可以存储的数据个数不一样
用户需要自行去测试!!!

源码执行效率
1.好的代码,一是稳定性,二是执行效率
其实操作Flash要想执行效率高,就不要频繁的擦除!
当前程序是存储25次数据,擦除一次Flash.

819239-20200905162649261-1333787957.png



结语
该缓存适合经常操作数据的场合,
不经常操作的数据请用户存到别的地方!!!
不要把所有的数据都用这个方案缓存,因为没有意义!

回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|论武天地论坛

GMT+8, 2024-3-29 13:22 , Processed in 0.087683 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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