zoukankan      html  css  js  c++  java
  • 数据处理思想和程序架构: 单片机stm32的flash保存数据优化方案(让擦写次数达到上百万至上千万次)

    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/单片机知识点总结/directory.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    说明

    此套方案是刚刚给别人做的项目的一个存储方案,因为很实用,几乎大家都用的到,所以分享给大家使用!

    制作原因:

    我项目上使用的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万次

    源码使用

    1.需要这两个文件

    用户把以下两个文件移植到自己的工程即可使用!

    2.存储数据

    1.请用户自行修改Flash的大小和存储数据的页地址

    2.默认最大存储20个数据(u16型),第一个和最后一个不可用,最大存储18个数据

    请用户根据自己的需求修改!

    3.把数据存储到Flash

    4.关于存储的数据

    用户把数据放到了数组  flash_helper_struct.FlashHelperData[XXX]  里面, XXX范围1-18.

    然后调用一下刷新函数,数组里面的数据就存储到了flash里面;

    用户获取先前存入的数据实际上只需要从 flash_helper_struct.FlashHelperData[XXX]  数组里面获取.

    因为数据就是缓存在数组里面的.

    如果用户需要知道Flash是不是存储成功了,用户需要在调用完刷新以后紧接着调用

    FlashHelperGetIndex(XXX);//XXX是索引,要和上面数组的下标保持一致.

    3.设备重启以后获取先前存入的数据

    1.在初始化存储函数后面直接用索引获取即可!

    简要概括

    1.实际上存数据就是把数据写到

    flash_helper_struct.FlashHelperData 数组

    然后调用  FlashHelperUpdate();函数刷新一下即可!

    注意:

    flash_helper_struct.FlashHelperData[0] //第一位

    和 flash_helper_struct.FlashHelperData[19]  //最后一位

    我作为了数据开头和结尾标识,用户不能使用

    用户可以用 FlashHelperGetIndex函数获取刚刚写入的数据

    用来判断是不是写入成功.

    如果写入不成功可以再次调用 FlashHelperUpdate();函数

    然后再调用 FlashHelperGetIndex函数获取刚刚写入的数据

    扩展(掉电存储)

    代码是先写入再判断擦除,一是保证确实写进去,二是为了下面的问题.

    假设写入数据的时候突然断电了

    用户可以在断电中断函数里面重新设置一下数组的值

    然后调用一下刷新函数!

    注意:单片机的vbt引脚需要接备用电池!

    测试程序是在掉电瞬间把数组FlashHelperData[1]的值改为30后存储到flash

    用户可以测试一下给单片机断电上电,然后看下存储的数据.

    源码执行效率

    1.好的代码,一是稳定性,二是执行效率

    其实操作Flash要想执行效率高,就不要频繁的擦除!

    当前程序是存储25次数据,擦除一次Flash.

    结语

    该缓存适合经常操作数据的场合,

    不经常操作的数据请用户存到别的地方!!!

    不要把所有的数据都用这个方案缓存,因为没有意义!

  • 相关阅读:
    值类型、引用类型作为方法参数如何执行,ref与out的区别
    asp.net 常用 验证正则表达式
    ASP.NET的错误处理机制
    MSSQL与MYSQL区别
    http协议状态码对照表
    EF 跨数据库支持
    请求管道中的19个事件
    一位软件工程师的6年总结本人读了深受启发,献给所有从事IT开发的人 [转载]
    Windows 窗体的.Net 框架绘图技术
    Windows Live Messenger 8.5 去广告方法及资源文件
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/13616968.html
Copyright © 2011-2022 走看看