FLASH延长写寿命算法

NOR(或非)和NAND(与非)是市场上两种主要的Flash闪存,sNORFLASH 和CPU之间不需要其他电路控制,NOR flash可以芯片内执行程序,而NAND FLASH 和CPU 的接口必须由相应的控制电路进行转换, NAND FLASH 以块的方式进行访问,不支持芯片内执行。 
    NAND FLASH 比NOR FLASH 容量大,价格低, NAND flash中每个块的最大擦写次数为100万次,而NOR 10W次, FLASH 编程原理都是只能把1变成0,而不能把0写为1, 所以在FLASH 编程之前,都要把对应的块擦除,擦除的过程就是把所有位都写为1,块内所有字节都变为0xFF。

    NAND Flash芯片的种种不足,则需要靠控制芯片或操作系统软件来补足,动态平均抹写(Dynamic Wear Leveling)就是NAND Flash控制芯片技术上的一项重要设计,可以将写入的资料平均在每一个NAND Flash芯片的区块上,而非重复写入同一个区块,造成NAND Flash芯片的损害,可以顺利延长NAND Flash芯片使用寿命,因此Wear-Leveling技术几乎是NAND Flash控制芯片设计上的必备。

Static Wear Leveler

    Let the Static Wear Leveler (SW Leveler) be associated with a Block Erasing Table (BET) to remember which block has been erased in a selected period of time. The SW Leveler is activated by some system parameters for the needs of static wear levelling. When the SW Leveler is running, it either resets the BET or picks up a block that has not been erased so far (based on the BET information) and triggers the Cleaner to do garbage collection on the block. The selection procedure of a block must be done in an efficient way within a bounded amount of time. Note that the BET must be updated whenever a block is erased. It could be done by a triggering action to the SW Leveler. The design of the BET must be scalable because of the rapid increasing of flash-memory capacity and the limited RAM space on a controller. Whenever a block is recycled by garbage collection, any modification to the address translation is done as the original design of a Flash Translation Layer driver. The implementation of the SW Leveler could be a thread or a procedure triggered by a timer or the Allocator/Cleaner based on some preset conditions.

The SW Leveler is invoked by the Cleaner to update the BET whenever any block is erased by the Cleaner in garbage collection when static wear levelling is needed. We can use two variables to keep track of the total number of block erases done since the BET is reset and the number of 1’s in the BET. If the ratio of the two tracked number is too high, the SW Leveler is triggered to move cold data from their original place by requesting the Cleaner to reclaim those blocks whose corresponding bit in the Block Erasing Table is 0.

Block Erasing Table

    The purpose of the Block Erasing Table (BET) is to remember which block has been erased in a pre-determined time frame, referred to as the resetting interval, so as to locate blocks of cold data. A BET is a bit array, in which each bit corresponds to a set of 2k contiguous blocks where k is an integer that is larger or equal to 0. Whenever a block is erased by the Cleaner, the SW Leveler is triggered to set the corresponding bit as 1.

    动态平均读写解决了块的 Erase 周期的次数限制。动态平均读写算法并不是随机使用可用的块,而是平均使用块,因此,每个块都获得了相同的使用机会。静态平均读写算法解决了一个更有趣的问题。除了最大化 Erase 周期的次数外,某些 flash 设备在两个 Erase 周期之间还受到最大化 Read 周期的影响。这意味着如果数据在块中存储的时间太长并且被读了很多次,数据会逐渐消耗直至丢失。静态平均读写算法解决了这一问题,因为它可以定期将数据移动到新块。

    开发电子产品时,常常需要断电后保存某些数据,这就需要使用FLASH或EEPROM芯片,这两种芯片,可擦除的次数是有限制的,通常FLASH为10万次,EEPROM要多一点,为100万甚至1000万次。FLASH的擦除不能单个字节进行,有一个最小单位,存储容量相对比较大,适合大量数据的存储;EEPROM可以单个字节进行擦除,存储容量不大,只适合存储少量的设置数据。

    先以FLASH和EEPROM需要写入一个字节为例来说明新数据是如何写入的。假定都是在首地址要写入新数据0x55。不管是FLASH还是EEPROM

    对于FLASH,写操作只能将数据位从1改写为0,如果想要将数据位从0改为1,就需要进行擦除操作,而且这个擦除最小单位是page(可能是256字节或更多)。现在要在首地址写入0x55,稳妥的方法是先擦除这个地方,也就是要擦除第一个page,擦除操作会一并将首地址后面的另外255个字节也擦除掉,如果这255个字节保存有其它数据,还需要把这些数据先进行备份,擦除第一个page后再将0x55和备份的255个字节写进去。也不是必须擦除第一个page,写操作可以完成数据位1到0的转变,利用这一特性结合首地址原来的内容,我们就有可能不用进行擦除操作,比如原来内容为0xFF,显然可以直接写入0x55,原内容为0xF5,同样也可以写入0x55,但如果原内容为0xAA,执行写0x55则会得到完全错误的结果,写完后内容依然为 0x00,因为对于0x55所有需要保持为1的位数据0xAA都是0,写0x55会把0xAA为1的位全清0,原来为0的位不会改变。

    对于EEPROM,写操作既可以将数据位从1改写为0,也可以将数据位从0改写为1,不需要进行单独的擦除操作,要写0x55直接将0x55写到首地址,不管原来内容为什么,完成写操作后内容都是0x55。
一开始我们说了FLASH和EEPROM都有可擦除的最大次数(EEPROM实际上没有擦除操作),虽然这个数字看着不小,但对于程序来说并不大,比如 EEPROM为10万次,如果我们以每秒一次的间隔依次写入0xFF和0x00,则只能维持100000/3600=27.78小时,也就是一天多就可以超出其最大寿命次数,不能再可靠写入所需的内容。

    这种可写入的最大次数是芯片的特性决定的,我们无法改变,所以在使用这些芯片时,我们应充分考虑最大写入次数这一参数,要确保产品在实际工作中不超过这一参数。实际上许多时候只要程序做出针对性处理,有可能让产品的最大写入次数超过芯片的寿命,还是以EEPROM来做说明。

    假定现在有一个产品,需要保存一些参数,参数的个数并不多,总共为10个字节,用EEPROM来保存就可以满足需求,我们选用了容量为256字节的 EEPROM,如果我们不做过多考虑,很有可能就是直接将这10个字节从EEPROM的首地址开始保存,每次改写也是直接修改这部分内容,这样我们最多可以保存参数10万次。只要我们做一点简单处理,就可以将保存参数的次数成倍增加,来看看我们应该如何实现。

 

        直接保存的最简方法:

        地址 0x00   0x01   0x02   ...  0x09

        内容 data1 data2 data3  ...  data10

 

        改进的保存方法:

        处理方法是将256字节按16字节大小分成16等份,按后面格式存储参数
        地址:

0x10*n +0x00 +0x01  +0x02 ... +0x09  +0x0A  +0x0B +0x0C  +0x0D +0x0E +0x0F
        内容:

flag     data1 data2 ...  data9  data10  保留1  保留2  保留3   保留4  check_sum

         check_sum=(flag+data1+data2+...+data10+保留1+...+保留4 )&0xFF
        flag为0xA5表示当前16个字节为正在使用的记录,为其它值表示当前16字节已经丢弃

        读取参数的时候先从地址0x10*n+0x00读flag,如果为0xA5表明当前记录为正在使用中,读出全部内容,并按前面公式进行校验,如果校验出错,则当前参数不可靠,直接使用默认参数,并将当前区域的flag改写为0,同时在地址0x10*(n+1)位置开始将默认参数写入,地址0x10* (n+1)写入内容为0xA5。如果所有区域都没有发现有效记录,在地址0写入默认参数。

        每次需要更改参数设定时,先将当前记录位置的flag改为0,然后再下一条记录位置写入新的参数,这个顺序可以做出适当改进,比如对写入时断电等意外情况做出考虑,从而得到更可靠的写入结果,不过就按此方法也都可以满足应用需求。

        再来对比一下两种方法,最简方法只能保存10万次,改进的方法理论上增加了16倍,达到160万次,如果预估最简方法产品是3年内绝对不会出错,现在就增加到了48年,一个电子产品使用超过3年还是有可能,但用48年的可能性就非常之小,可以视同为0。对于FLASH芯片也是同样道理,这里就不重复举例说明,在应用中也应该做出同样的处理。

 

《用变址寻址原理突破EEPROM存储器的擦写寿命极限》

    一般地,EEPROM存储器(如93C46/56/66系列)的擦写次数为10万次,超过这一极限时,该单元就无法再使用了。但在实际应用中,可能有些数据要反复改写。这时,可通过变址寻址的方式来突破EEPROM存储器的擦写寿命极限。

    比如,我们有一个单字节的数据要保存在E2PROM(93C56)中,可按以下方法来做:

    1、将93C56的00H单元定义为地址指针存放单元。
    2、将要寻址的单元地址(假设为01H)放入93C56的00H地址中。
    3、每次要对E2PROM中的数据进行读写时,先读取00H中的数据,并以读出的值为地址,访问其指向的单元。
    4、在每次写完数据后,立即将数据再读出,并与写入的地址做比较。
        A、如果相等,则代表本次写入数据成功。
        B、如果不相等,则代表本次写入数据失败。这时,将00H中的值+1,让其指向后一个新的地址单元,再将数据写入新的地址单元。
   
    93C56共有128个字节单元,按照以上方法,可将数据的擦写次数提升120多倍!达到1200多万次!

    对于24C16/32/64系列的芯片,也可采用这种方法。

    这个方法,小匠使用过多次,证明是可行的。

 

补充二点

1. EEPROM单元坏与不坏界线很是模糊. EEPROM单元能写入信息是因为它的浮栅能俘获电子并将其困在其中. 但随着时间的推移电子由于热运动或外界给予能量会逐渐逃逸, 所以说EEPROM保持信息是有一定年限的(比如100年). 写入与擦除信息即是向浮栅注入和释放电子,电子能量比较高,可能改变周围的晶格结构,导致浮栅俘获电子能力的下降,也就是表现为保存信息的时间变短, 所以才会有一个保守的写入次数限制(这里说保守是因为半导体的离散性大,实际的次数大得多). 到了规定写入次数并不是说该单元就坏了, 而是说该单元保持信息的时间已不可信赖(而实际上它可能还能保存相当长时间甚至几十上百年),所以实际上短时间很难判定某个单元是否可用(坏了). 如匠人的方法检测, 写入时测试好好的, 可能几秒钟之后该单元的数就逃了.

2. 写坏一个单元是很费时间的, "这个方法,小匠使用过多次,证明是可行的。", 不知匠人在使用过程中是否碰到过有写坏的情况?

个人意见请朋友们扔....

 

 云起 发表于 2002-1-22 05:01 侃单片机 ←返回版面    

可以改进

00H存放地址,01H 02H存放次数,每次读写次数+1,达到65535次(FFH),地址指针+1,轮流写过去。

 

1、SOHO的分析真是深刻,你提出“写入时测试好好的, 可能几秒钟之后该单元的数就逃了.”我想,如果用亢余技术来处理的话,也许能回避你所说的问题。

2、TO 云起:你的方法是不可行的,如果按你的方法,数据改写10万次, 01H 02H单元的次数也改写了10万次,那不是也坏了吗?

3、TO telesoft :你的担心是多余的,时序的问题,小匠当然考虑到了。;--)

4、TO jw5th:被你称为“智者”,小匠真是脸红……

 soho 发表于 2002-1-22 20:22 侃单片机 ←返回版面    

匠人提供了一个好思路, 方法稍作修改如何

为了保证EEPROM内的数据可以长久保存, 每个单元的写入次数不能超过规定的限值, 借用匠人和云起的思路,本人提出改进方案:

数据以块为单位存放, 每块可取4个字节, 前三个字节记录写入次数,第四个字节为要保存的数. 每次作写入操作时, 把次数+1连同数据一超写入EEPROM.
EEPROM前面开辟一个索引指针区(可供N个数据保存用), 存放数据块的地址由指针计算所得, 计算方法是:基址+指针值*数据块长度. 当某块区域的写入次数到达时, 调整指针指向下一个可用的数据区域.

这样,EEPROM的空间利用率<<25%, 用来换取写入次数>>写入寿命, 方法是否可取, 请诸位拍转.

 

 

 程序匠人 发表于 2002-1-25 23:36 侃单片机 ←返回版面    

妙啊!

晓奇的方法很好!

优点是明显的:
EEPROM的空间利用率大为提高,尤其是当要保存的数据为多字节时。

当然,还有一些需要改进的地方:
1、每次读写数据时都要去找当前的活动区,未免太让CPU操劳了。
2、万一EEPROM中有一个单元的革命意志不坚定,提前退休了,那整片芯片也就完蛋了(这就是所谓的水桶效应——水桶的容量取决于最短的那块板)
3、如果每次要改写的只是个别数据,那怎么办呢?

不管怎么样,这个思路不错,如果再完善一下,一定是个好方法。

 

 zxcasd 发表于 2002-1-26 03:27 侃单片机 ←返回版面    

看来晓奇的"要死一起死"的办法最好了

 

 xgdzd 发表于 2002-1-27 23:32 侃单片机 ←返回版面    

晓奇的方法很好!但是……

“同时对上一次为'55'的标志字节写入'aa'”,则作为标志的字节其写入次数是数据区的2倍,恐怕要提前“壮烈牺牲”了,难以做到“要死一起死”。若能解决则不失为“妙法”!!!

 

 xiaohh2000 发表于 2002-1-28 10:35 侃单片机 ←返回版面    

改良

在晓奇的方法上稍做改进如下:把标志字放在最后,(顺便说一句,标志字最好分析一下系统,取一个系统不可能出现的数字,如果觉得1byte不可靠,可取2byte,另外标志字最好别选A,5之类).查找标志字再写数据(覆盖标志字),然后在所写数据的结尾写标志字.这样可以避免标志字写2遍的问题.至于查找指针的问题,我觉得可以这样:上电时读出写数指针放入RAM中,写了新数后更新指针.

 

 ymc8 发表于 2002-1-28 12:30 侃单片机 ←返回版面    

曾经使用过的方法

EEPROM用X25045:
不常改写的数据共30字节,写入第1~8页。
改写频繁的数据有2字节,保存在20H~1FFH中,以4字节页为单位使用,每页中前2字节作为计数器,后2字节为要保存的数据。
所有计数器第一次使用前先初始化为0FFH。读出数据时先读第一块的计数器,=0,则读下一块的计数器,非0,则直接读出。写入数据时,先读第一块的计数器,=0,则读下一块的计数器,非0,则直接写入,写入后计数器减1,若计数器=0,则同时写入下一块。最后一块写满65535次后,将所有计数器再初始化为0FFH,然后进入下一循环……
分析:
    每页中的四个字节写入次数相同,应该具有接近的寿命;
    共使用120页,理论寿命应是只用固定2个字节的120倍;
    大部分操作为读计数器,速度快,并且程序判定=0比较容易;
    空间利用率一般:50%
适用场合:系统对速度要求不高(若当前块为最后一块,则需读119次计数器);

有几台设备已写入200多万次(估算),目前仍在正常运转。

 

 

 xiaohh2000 发表于 2002-1-28 13:32 侃单片机 ←返回版面    

对不起,俺没说清楚

设定eeprom的初值0xff.第一次写完数据后,在数据后写标志字.以后的操作:先找标志字,写数时,从标志字开始往后写(必须覆盖标志字),紧接着数据写标志字,读书时,从标志字往前读.  为了防止找标志字太费功夫,可以在系统上电时找到标志字的位置,记录在RAM中,并跟踪变化.  

 

 

 程序匠人 发表于 2002-2-5 23:06 侃单片机 ←返回版面    

匠人的改进方法

小匠的这篇帖子,引起大伙一些非常深入的讨论。小匠也从中找到了更完善的方法。不敢独吞,再次现丑了。

    首先回顾一下,我原来的方法:
    1、将93C56的00H单元定义为地址指针存放单元。
    2、将要寻址的单元地址(假设为01H)放入93C56的00H地址中。
    3、每次要对E2PROM中的数据进行读写时,先读取00H中的数据,并以读出的值为地址,访问其指向的单元。
    4、在每次写完数据后,立即将数据再读出,并与写入的地址做比较。
        A、如果相等,则代表本次写入数据成功。
        B、如果不相等,则代表本次写入数据失败。这时,将00H中的值+1,让其指向后一个新的地址单元,再将数据写入新的地址单元。


    我分析了一下,我要存入E2PROM中的数据为BCD码,并且它的规律是,每次改写都是递增的。在这种情况下,可以在我原先的方法做一些改进。
    即,每当被改写的数值递增后发生进位时,就将00H的值+1,让其指向后一个新的地址单元,再将数据写入新的地址单元。
    这里借用了晓奇的方法,——“要死一起死”,但是,却省下了大量标志的空间。从理论上来说,空间利用率可接近100%了。
  
      其实,在许多场合下,对于这种频繁改写E2PROM的情况,其改写的值都是有一定规律的,要么递增,要么递减,要么有其它规律,如果对这种规律善加利用,一定可做出最佳的程序。

      上述改进方法,我已用到最近的一个案子中了,尚待验证。当然,实际的程序要更复杂一些。
      各位有高见,请提出……

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux Flash 存储器的寿命取决于许多因素,包括芯片制造商、使用情况和存储器的类型。在日常使用中,可以采取以下措施来延长 Flash 存储器的寿命: 1. 避免频繁入: Flash 存储器的寿命与其被入的次数成正比,因此尽量避免频繁入。 2. 使用 Wear Leveling 技术: Wear Leveling 技术可以使 Flash 存储器中每个块被入的次数大致相等,从而延长整个存储器的寿命。 3. 禁用日志功能: 日志功能可以记录文件系统的变化,但每次入都会增加 Flash 存储器的使用次数,因此可以禁用日志功能来延长 Flash 存储器的寿命。 4. 使用 TRIM 功能: TRIM 功能可以告诉 Flash 存储器哪些块不再需要保存数据,从而使其能够更好地执行垃圾回收操作,延长 Flash 存储器的寿命。 至于 Flash 延长寿命算法,常见的有以下几种: 1. 块擦除算法: 将需要擦除的块标记为“已使用”,在需要入数据时,尽量使用已使用的块,从而实现块的平衡使用,延长 Flash 存储器的寿命。 2. 热点块算法: 标记频繁入的块为“热点块”,在需要入数据时,尽量避免使用热点块,从而减少块的擦除次数延长 Flash 存储器的寿命。 3. 延迟算法: 将需要入的数据缓存起来,当缓存区满时再进行批量入,从而减少次数延长 Flash 存储器的寿命。 以上是一些常见的 Flash 延长寿命算法,不同的场景和需求会有不同的算法选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值