最近研究了下nor flash的掉电问题,对nor的掉电有了更多的认识。总结分享如下

擦除从0变1,写入从1变0

nor flash的物理特性是,写入之前需要先进行擦除。擦除后数据为全0xFF,此时写入操作,实际上是将数据从1改成0。
一般先擦后写,但实际上擦除后每个位置是可以写入多次的,只要每次写入都是让某些bit从1变0即可。
例如在擦除后数据为0xFF,此时写入0x0F,可读出0x0F,再写入0x01,可读出0x01,再写入0x00,可读出0x00。
而对于0x00,就无法再改写成任何值了,因为此时每个bit都是0,想要改写就必须先擦除,让其恢复到0xFF,再进行写入改成目标值。

多次写入的例子

在uboot中就有一个利用nor这个特性的例子。当使用了冗余env功能时,flash上会维护两份env,我们记为envA和envB吧。
既然有两份env,那就需要一种方式来区分哪份env的数据更新。对此uboot支持几种策略,其中一种可适用于nor的策略FLAG_BOOLEAN,uboot会在env的头部结构中,使用了一个字节flags来表示其是否有效。
假设当前A有效,B无效,则A的flags为0x1,B的flags为0x0. 读取时可以据此判断哪份env为新的。
写入时,uboot会先在ram的buffer中构造好flags为1的新env数据,再对envB进行擦除和写入。写入后flash上两份env的flags就都是0x1了。接着uboot直接对A的flags的位置写入0x0,即将原本的0x1不经擦除,直接改写为0,这样就快速地达到将A标记为无效的目的了。

写入过程掉电

对于nor来说,一次写入可以连续写256 bytes,那如果在中途发生了掉电,再次上电后读出来的数据会是什么样的呢?
这个问题我们很容易得到两种猜测:
假设nor中存在一片buffer,集齐256 bytes后再一次性刷到颗粒中,那么中途掉电大概率就是完全没有写入,因为数据还在buffer中。也有小概率是正在刷buffer到颗粒中掉电了,那么这个时候写入的数据应该是乱序的。
假设nor中没有维护buffer,每个bytes的波形接收到之后就写入固化下来,那么中途掉电大概率就是部分写入,而且是顺序的,即前面的数据写入了,后面的数据仍然为0xFF。

实测实际情况为假设二所述。
当写入一笔数据时,nor就是按顺序写入的,掉电后的数据特征为前面部分数据是正确数据,后面部分数据是0xFF。前后的交界点并对齐到256 bytes。

擦除过程中掉电

从nor flash原厂了解到,erase操作其实在flash内部分成三个步骤:
1)pre-program all "00";
2)erase;
3)post-program all "FF"

那么在擦除过程中掉电,可能出现的数据特征就比较多了。

第一步骤:pre-program all "00";
当收到擦除命令时,首先flash会对这4k写入全0数据,这个是按先后顺序串行写入的,就理解为一个正常的写入全0数据。
如果在这个过程中掉电,那么观察到的数据会是,前半部分的数据为0x00,后半部分的数据为原始的数据。情况跟上面描述的写入过程掉电一样。

第二步骤:erase
全部写入0之后,就进行擦除,擦除是会将所有的0都变成0xFF,这个是4k的数据并行进行的,在这个过程中掉电,可以看到所有的数据都介于0-0xFF之间,乱七八糟的数据,没有任何规律。

第三步骤:post-program all "FF"
这一步其实我没太理解,但从掉电后的数据特征看,有一种状态可能跟这一步没完成有关。
即4k的数据,处于不稳定的0xFF状态。不稳定的意思是,某次上电读出来为全0xFF,重新上电再读,可能就是夹杂着一些0xFD, 0xBF之类的数据。

总结

以上我们观察了写入和擦除中途掉电的数据特征。
从写入过程掉电的特征看,写入过程掉电可能导致nor仅将部分数据写入的,导致头部数据存在但整体数据是不完整的,因此不能简单依赖头部结构的MAGIC值来判定数据是否有效,重要数据需要做完整性校验。
从擦除过程掉电的特征看,擦除过程掉电可能导致flash上存在杂乱数据,或者不稳定的全0xFF数据,因此对于全0xFF的数据,写入之前还是要先做一次擦除让nor达到稳定状态。

本文链接:https://www.cnblogs.com/zqb-all/p/12207924.html

nor flash之擦除和写入的更多相关文章

  1. 延长FLASH和EEPROM芯片写入次数的小方法

    开发电子产品时,常常需要断电后保存某些数据,这就需要使用 FLASH或EEPROM芯片,这两种芯片,可擦除的次数是有限制的,通常FLASH为10万次,EEPROM要多一点,为100万甚至1000万次. ...

  2. 分享STM32 FLASH 擦除(以及防止误擦除程序代码)、写入

    编译环境:我用的是(Keil)MDK4.7.2   stm32库版本:我用的是3.5.0一.本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料. 对STM32 内部FLASH进行编程操 ...

  3. 第50章 读写内部FLASH—零死角玩转STM32-F429系列

    第50章     读写内部FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  4. S03_CH11_基于TCP的QSPI Flash bin文件网络烧写

    S03_CH11_基于TCP的QSPI Flash bin文件网络烧写 11.1概述 针对ZYNQ中使用QSPI BOOT的应用,将BOOT.bin文件烧写至QSPI Flash基本都是通过USB C ...

  5. nor flash之4字节地址模式

    背景 容量低于 16M bytes 的 nor,一般使用 3 字节地址模式,即命令格式是 cmd + addr[2] + addr[1] + addr[0] + ... 使用超过 16M bytes ...

  6. 单片机固件烧录器 Firmware Writer Android APP

    GitHub地址 :https://github.com/WallBreakerX/mcu_firmware_writing_via_androidphone ​ 用途 可在安卓手机上实现向单片机的h ...

  7. 【转】stm32 IAP升级程序

      一.什么是IAP,为什么要IAP       IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经 ...

  8. 16经典的SPI Flash的扇区擦除flash_se功能

    一设计功能 对SPI_flash进行扇区擦除,分为写指令和扇区擦除两个时序部分. 二设计知识点 我简单理解flash,第一它是掉电不丢失数据的存储器,第二它每次写入新数据前首先得擦除数据,分为扇区擦除 ...

  9. 痞子衡嵌入式:其实i.MXRT下改造FlexSPI driver同样支持AHB方式去写入NOR Flash

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT下改造FlexSPI driver以AHB方式去写入NOR Flash. 痞子衡前段时间写过一篇 <串行NAND Fl ...

随机推荐

  1. 2019-7-29-WPF-元素裁剪-Clip-属性

    title author date CreateTime categories WPF 元素裁剪 Clip 属性 lindexi 2019-7-29 10:0:13 +0800 2019-1-3 15 ...

  2. 2019-8-30-C#-反射调用私有事件

    title author date CreateTime categories C# 反射调用私有事件 lindexi 2019-08-30 08:52:57 +0800 2018-09-19 20: ...

  3. java位运算和无符号运算

    计算机在底层使用的是二进制补码进行运算. 计算规则: 正数的原码.反码.补码是其二进制本身. 负数的原码首先计算其二进制数,然后最高位使用1表示负数,反码是最高位不变其它位取反,补码是在反码的基础上进 ...

  4. 【t066】致命的珠宝

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 门上有着N个宝珠,每个宝珠都有一个数字.Mini询问老者后,得知要想打开这扇门,就得找出两颗珠宝,使这 ...

  5. swiper 使用参考 禁止手动滑动 监听事件

    最外层容器加类名  swiper-no-swiping 监听切换事件 onTransitionEnd: function(swiper){ console.log('过渡结束'); }

  6. java 如何重写equals

    java中重写equals表面上看只涉及equals与hashCode两个方法,但如果仔细考虑发现重写一个逻辑完整的equals并不容易,需要考虑克隆,继承(多态)等问题,下面是最近的几点心得 1.先 ...

  7. char* 、const char*和string之间的转换

    1. const char* 和string 转换 (1) const char*转换为 string,直接赋值即可.     EX: const char* tmp = "tsinghua ...

  8. python监控模块

    pip install psutil 获取内存信息: >>> import psutil >>> mem = psutil.virtual_memory() #获取 ...

  9. K:缓存数据库双写数据一致性方案

    对于缓存和数据库双写,其存在着数据一致性的问题.对于数据一致性要求较高的业务场景,我们通常会选择使用分布式事务(2pc.paxos等)来保证缓存与数据库之间的数据强一致性,但分布式事务的复杂性与对资源 ...

  10. lintcode入门37-算法实现

    lintcode入门级算法题37 一.题目 反转一个3位整数 反转一个只有3位数的整数. 样例          样例 1: 输入: number = 123 输出: 321         样例 2 ...