这里分享一下在嵌入式设备的存储器科普。
一、存储器科普
RAM
、SRAM
、SDRAM
、ROM
、EPROM
、EEPROM
、Flash
存储器可以分为很多种类;其中根据掉电数据是否丢失可以分为RAM(随机存取存储器)和ROM(只读存储器),其中RAM的访问速度比较快,但掉电后数据会丢失,而ROM掉电后数据不会丢失。
1.1 常见存储器
在嵌入式开发过程中,往往会涉及到存储器(掉电存储等功能);其中的 Flash,EEPROM,SRAM耳熟能详。
- Flash,适用于速度要求高,容量要求大,掉电时要求数据不丢失的场合
- EEPROM,适用于速度不高,容量不大,掉电时要求数据不丢失的场合
- SRAM,一般就相当于计算机的内存,断电不保存,读写速度比flash, eeprom快N倍
在单片机中,往往RAM主要是做运行时数据存储器,FLASH主要是程序存储器,EEPROM主要是用以在程序运行保存一些需要掉电不丢失的数据。
- FLASH:单片机运行的程序存储的地方
- SRAM:存储单片机运行过程中产生的了临时数据
- EEPROM:视用户的需要而定,一般用来存储系统的一些参数,这些参数可能需要修改,也可能不会修改。
1.2 EEPPROM 和 Flash 混淆来由
EEPROM的全称是“电可擦除可编程只读存储器”,即Electrically Erasable Programmable Read-Only Memory。是相对于紫外擦除的rom来讲的。但是今天已经存在多种EEPROM的变种,变成了一类存储器的统称。
狭义的EEPROM:这种rom的特点是可以随机访问和修改任何一个字节,可以往每个bit中写入0或者1。这是最传统的一种EEPROM,掉电后数据不丢失,可以保存100年,可以擦写100w次。具有较高的可靠性,但是电路复杂/成本也高。因此目前的EEPROM都是几十千字节到几百千字节的,绝少有超过512K的。
Flash:属于广义的EEPROM,因为它也是电擦除的ROM。但是为了区别于一般的按字节为单位的擦写的EEPROM,我们都叫它Flash。
FLASH按扇区操作,EEPROM则按字节操作;二者寻址方法不同,存储单元的结构也不同,FLASH的电路结构较简单,同样容量占芯片面积较小,成本自然比EEPROM低,因而适合用作程序存储器,EEPROM则更多的用作非易失的数据存储器。当然用FLASH做数据存储器也行,但操作比EEPROM麻烦的多;所以更“人性化”(成本)的MCU设计会集成FLASH和EEPROM两种非易失性存储器,而廉价型设计往往只有 FLASH,早期可电擦写型MCU则都是EEPRoM结构,现在已基本上停产了。
EEPROM:电可擦除可编程只读存储器,Flash的操作特性完全符合EEPROM的定义,属EEPROM无疑,首款Flash推出时其数据手册上也清楚的标明是EEPROM,现在的多数Flash手册上也是这么标明的,二者的关系是“白马”和“马”。至于为什么业界要区分二者,主要的原因是 Flash EEPROM的操作方法和传统EEPROM截然不同,次要的原因是为了语言的简练,非正式文件和口语中Flash EEPROM就简称为Flash,这里要强调的是白马的“白”属性而非其“马”属性以区别Flash和传统EEPROM。
Flash的特点是结构简单,同样工艺和同样晶元面积下可以得到更高容量且大数据量下的操作速度更快,但Flash缺点是操作过程麻烦,特别是在小数据量反复重写时,所以在MCU中的Flash结构适于不需频繁改写的程序存储器。
很多应用中,需要频繁的改写某些小量数据且需掉电非易失,传统结构的EEPROM在此非常适合。所以很多MCU内部设计了两种EEPROM结构,FLASH的和传统的以期获得成本和功能的均衡,这极大的方便了使用者。随着ISP、IAP的流行,特别是在程序存储地址空间和数据存储地址空间重叠的MCU系中,现在越来越多的MCU生产商用支持IAP的程序存储器来模拟EEPROM对应的数据存储器,这是低成本下实现非易失数据存储器的一种变通方法。为在商业宣传上取得和双EEPROM工艺的“等效”性,不少采用Flash程序存储器“模拟”(注意,技术概念上并非真正的模拟)EEPROM数据存储器的厂家纷纷宣称其产品是带EEPROM的,严格说,这是非常不严谨的,但商人有商人的目的和方法,用Flash“模拟”EEPROM可以获取更大商业利益,所以在事实上,技术概念混淆的始作俑者正是他们。
1.3 Flash的粗分
目前Flash主要有两种,NOR Flash和NAND Flash。
- NOR Flash:NOR Flash的读取和我们常见的SDRAM的读取是一样,用户可以直接运行装载在NOR FLASH里面的代码,这样可以减少SRAM的容量从而节约了成本。
- NAND Flash:NAND Flash没有采取内存的随机读取技术,它的读取是以一次读取一块的形式来进行的,通常是一次读取512个字节,采用这种技术的Flash比较廉价。
Ps :用户不能直接运行NAND Flash上的代码,因此很多使用NAND Flash的开发板除了使用NAND Flash以外,还作上了一块小的NOR Flash来运行启动代码
一般小容量的用NOR Flash,因为其读取速度快,多用来存储操作系统等重要信息,而大容量的用NAND FLASH,最常见的NAND FLASH应用是嵌入式系统采用的DOC(Disk On Chip)和我们通常用的“闪盘”,可以在线擦除。目前市面上的FLASH 主要来自Intel,AMD,Fujitsu和Toshiba,而生产NAND Flash的主要厂家有Samsung和Toshib
二、Flash的前世今生
2.1 Flash起源
Nand Flash 和 Nor Flash
是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR Flash 技术,彻底改变了原先由EPROM(Electrically Programmable Read-Only-Memory电可编程序只读存储器)和EEPROM(电可擦只读存储器Electrically Erasable Programmable Read - Only Memory)一统天下的局面。紧接着,1989年,东芝公司发表了NAND Flash 结构,强调降低每比特的成本,有更高的性能,并且像磁盘一样可以通过接口轻松升级。NOR Flash 的特点是芯片内执行(XIP ,eXecute In Place),这样应用程序可以直接在Flash闪存内运行,不必再把代码读到系统RAM。
注:
片内执行不是说程序在存储器内执行,CPU的基本功能就是取指、译码和执行。Nor Flash能在芯片内执行,就是指CPU的取指模块能够直接从NorFlash中把指令取出来,供后面的译码和执行模块使用。
2.2 Flash的差异
由于Nor Flash的接口与RAM完全相同,可以随机访问任意地址的数据。因此,Nor Flash进行读操作的效率非常高,但是擦除和写操作的效率很低,另外,Nor Flash的容量一般比较小。
而NAND Flash的接口仅仅包含几个I/O引脚,需要串行地访问。NAND Flash一般以512字节为单位进行读写。这使得Nor Flash适合于运行程序,而NAND Flash更适合于存储数据。
容量相同的情况下,NAND Flash的体积更小。市场上Nor Flash的容量通常为1MB4MB(也有32MB的Nor Flash),NAND Flash的容量为8MB512MB。对于空间有严格要求的系统,NAND Flash可以节省更多空间。容量的差别也使得Nor Flash多用于存储程序,NAND Flash多用于存储数据。
对于Flash存储器件的可靠性需要考虑3点:位反转、坏块和可擦除次数。所有Flash器件都遭遇位反转的问题:由于Flash固有的电器特性,在读写数据过程中,偶然会产生一位或几位数据错误(这种概率很低),而NAND Flash出现的概率远大于Nor Flash,当位反转发生在关键的代码、数据上时,有可能导致系统崩溃。当仅仅是报告位反转,重新读取即可:如果确实发生了位反转,则必须有相应的错误检测/恢复措施。在NAND Flash上发生位反转的概率史高,推荐使用EDC/ECC进行错误检测和恢复。NAND Flash上面会有坏块随机分布在使用前需要将坏块扫描出来,确保不再使用它们,否则会使产品含有严重的故障。
NAND Flash每块的可擦除次数通常在100000次左右,是Nor Flash的10倍。另外,因为NAND Flash的块大小通常是Nor Flash的1/8,单块的擦除需求更少,所以NAND Flash的寿命远远超过Nor Flash。
- | Nor | NAND |
---|---|---|
XIP(代码可以直接运行) | Yes | No |
性能(擦除) | 块大,非常慢(5s) | 块小,快(3ms) |
性能(写) | 慢 | 快 |
性能(读) | 快 | 快 |
可靠性 | 较高,位反转的比例小于NAND Flash的10% | 比较低,位反转比较常见,必须有校验措施。且比如TNR必须有坏块管理措施 |
可擦除次数 | 10000 ~ 100000 | 100000 ~ 1000000 |
生命周期 | 低于NAND Flash的10% | 是Nor Flash的10倍以上 |
接口 | 与RAM接口相同 | I/O接口 |
易用性 | 容易 | 复杂 |
主要用途 | 常用于保存代码和关键数 | 用于保存数据 |
价格 | 高 | 低 |
三、 Nand Flash
由于Nand Flash的可靠性(位反转、坏块),在比较低端的嵌入式设备并不采用Nand Flash,其容量大、擦写次数多在低端嵌入式设备中体现不出优势。Nand Flash会被采用于 嵌入式Linux设备,常见于使用NAND Flash的开发板除了使用NAND Flash以外,还作上了一块小的NOR Flash来运行启动代码。在linux上很多现成、高级的驱动,因此这里就不多讲Nand Flash。
我们写Nand Flash驱动,是写Nand Flash 控制器的驱动,而不是Nand Flash 芯片的驱动,因为独立的Nand Flash芯片,一般来说,是很少直接拿来用的,多数都是硬件上有对应的硬件的Nand Flash的控制器,去操作和控制Nand Flash,包括提供时钟信号,提供硬件ECC校验等等功能,我们所写的驱动软件,是去操作Nand Flash的控制器,然后由控制器去操作Nand Flash芯片,实现我们所要的功能。
四、Nor Flash
Nand Flash需要高级(算法处理)驱动,对低端嵌入式设备是一种考验。由于低端嵌入式设备往往对数据量要求不大,且对可靠性要求较高,往往采用Nor Flash。常见的用法是用于存储设备的历史记录,常见芯片有W25Qx系列的Nor Flash。
4.1 Flash的擦除
像EEPROM等其他储存芯片是没有擦除这一说的。例如,iic接口的AT24Cx芯片,想要写入的数据直接覆盖在对应地址的数据上。
Nor Flash的物理特性是,写入之前需要先进行擦除。擦除从0变1,写入从1变0。
擦除后数据为全0xFF,此时写入操作,实际上是将数据从1改成0。
一般先擦后写(常见于W25Qx驱动),但实际上擦除后每个位置是可以写入多次的,只要每次写入都是让某些bit从1变0即可。
例如,在擦除后数据为0xFF,此时写入0x0F,可读出0x0F,再写入0x01,可读出0x01,再写入0x00,可读出0x00。而对于0x00,就无法再改写成任何值了,因为此时每个bit都是0,想要改写就必须先擦除,让其恢复到0xFF,再进行写入改成目标值。
4.2 “块,扇,页”的区别
从上面的擦除概念,引申出(硬件)磁盘的最小擦除单位(Sector)。这里的单位概念有:块(Block),扇(Sector),页。
- 从底层驱动层面上看,Sector是最小存储单位(而且从驱动层面看并没有block的概念)
- 从软件(OS、文件系统)层面上看,Block才是文件存取的最小单位
OS、文件系统不是一个扇区一个扇区的来读数据,太慢了,所以有了block(块)的概念,它是一个块一个块的读取的,Block才是文件存取的最小单位)。
- Block由一个或多个Sector组成;
- Block是软件(OS、文件系统)中最小的操作单位
- Sector是 底层驱动的最小操作单位(擦写)
- Block值一般与sector值是不相等的
因此,在其他地方看到块为最小单位、扇为最小单位时,就可以知道他是以什么层面来看待存储的。
- Block是文件系统上的概念,一般文件系统block大小为4K(可以灵活设置块的大小)
- Sector是磁介质硬盘最小单元,一般为512字节(现在有4K的了)
- 至于页,是为了驱动方便擦写、检测扇内部的写入情况,提出来的一个概念;实际上并没有多大关系。如果进行擦除,还是会以Sector做为最小单位进行擦除操作
4.3 坏块 & 写平衡
这里先讲 坏块 这个概念。由于刚接触Flash底层的人,然后又经常听谁谁谁的移动硬盘坏块很多,或者是建议买硬盘后先做个坏块检测之类的事情。
真正意义的 “坏块”
闪存内的坏块处理,是指生产出的闪存并不是完美的,总会有某些比特或者某些区域不可使用,这时候就要对闪存进行坏块处理。
一开始生产的时候,发现到这个问题,想处理这些坏块。但是呢,由于处理起来成本太高(即,良品率太低),索性就让他坏块,出厂前做下坏块处理,检测一下坏块数量不多就出厂了。
Nand Flash是存在挺多坏块的。我们那些移动硬盘,那么大容量,当然是采用Nand Flash做成的。至于遇到所谓的黑心商家,就是把坏块率高的(或者寿命较短,因为用过的)移动硬盘(Nand Flash)卖给你。
Nor Flash没有坏块(你可以认为)。实际上 Nor Flash 是存在坏块的,只不过是在内对坏块进行了处理。
另类的 “坏块”
另类的坏块,即寿命到了产生的不可写区域。一般人会混淆,认为不能用就是坏块(其实也算)。寿命到了不一定就不能用,只不过是容易产生”坏块”。尤其是嵌入式设备的Flash,由于对数据量要求不高,且对稳定性有高要求,往往采用的是Nor Flash做数据存储。
但是Nor Flash的擦写寿命相对较短,寿命将至闪存可能会工作异常(产生”坏块”)。写平衡(又名 磨损平衡、负载平衡)便应运而生。
由于Nor Flash的Sector(block),都是有一定寿命限制的,所以如果你每次都往同一个Sector(block)擦除然后写入数据,稍微长时间,那么那个Sector(block)就很容易被用坏了。所以我们要去管理一下,将这么多次的对同一个Sector(block)的操作,平均分布到其他一些Sector(block)上面,使得在Sector(block)的使用上,相对较平均,这样相对来说,可以更能充分利用Nor Flash。
只进行一次大规模的擦除,后续的操作只需要进行写和读;写过的区域不再重写,读取的数据根据自己的需求算法,查出在Nor Flash的位置地址,读取想要的数据。当整个Nor Flash接近写满时,重新大规模擦除前,需要注意先擦除小部分区域,把所需的数据先读取出来,再重写入新擦除区域保存。
写平衡,将空闲的Sector(Block)运用起来,进而将Nor Flash的寿命变相翻倍。