智能座舱之存储篇第二篇---FLASH有趣的介绍

作者 / 阿宝

编辑 / 阿宝

出品 / 阿宝1990(微信ID woabao1990)

今天主要介绍的是掉电后依旧能保存程序的器件,FLASH,在我们实际设计的产品中会经常遇到的无非是这几类存储,E2PROM、NOR FLASH、NAND FLASH、EMMC等这几大类,今天机哥就针对这几类在车载上分别有什么应用,注意事项。

EEPROM 低功耗、高擦写次数的首选方案

EEPROM 的全称是“电可擦除可编程只读存储器”,可以在电脑上或专用设备上擦除已有信息,重新编程,一般用在即插即用。在一些所需存储容量不大,并且需要频繁更新的场合, EEPROM 相比较于Flash ,由于其百万次的擦写次数和更快速的写入,成为更佳选择。

近年来,EEPROM 除了越来越多的集成到 SOC 芯片中,也可搭配 AMOLED、指纹、触控、摄像头、蓝牙、无线等芯片形成模组。EEPROM 以其通用性,稳定耐用的数据存储,各种小容量规格,能满足摄像头模组、可穿戴设备等对参数存储的要求。

也许你会说,机哥哪里有这么多擦写次数要求的使用场景哦,不会达到百万次啊。机哥给你说说一个场景,车载液晶仪表的总里程数,目前汽车的里程基本上是都是通过液晶仪表仪表的EEPROM里面进行存储,每隔一定的时间,总的里程数就会增加,这个数据就会发生变化,就会往EEPROM里面写入,想想假如1分钟写一次,那么10年就要写5256000次,当然这里不会这么夸张,车辆10年都一直不停歇,同时EEPROM的存储大小也是要写很多次后再进行覆盖擦除,不是每写一次就直接覆盖掉了,这样EEPROM的寿命是无法满足车辆的寿命周期的。

还有就是在娱乐中控导航中,有一些掉电要保持的数据,比较常见的功能就是掉电记忆,比如用户上次的收音节目是哪个频道,这样更用户更好的体验效果,此时就需要使用到一颗EEPROM,每次去保持这个数据,因为每次用户最后关机的状态是不同的,比如这次在听MP3的某首歌,下次再听FM收音某个频道,此时都需要去刷写EEPROM,而且为了防止突然掉电,很多ter1的做法都是固定的时间去存储一下这个用户数据个性化数据进入EEPROM,哪怕是突然掉电,它依旧存储了突然掉电前最近的一次用户操作。

因为EEPROM的容量有限,所以决定了该器件的用途主要是用来存储一些参数,而且是存储一些需要经常擦写的数据。无法存储启动程序等等,因为目前的ARM架构的boot程序都无法放置在EEPROM中。

NOR FLASH & NAND FLASH 最佳搭档

吃瓜群众:什么样的搭档才是最佳搭档?

机哥:这样说吧,吃过槟榔的朋友都知道,槟榔的最佳搭档就是香烟,俗话说的好,槟榔加烟,法力无边。

机哥在做机顶盒的时候,很多项目都是NOR FLASH +NAND FLASH的配置,刚开始我也不懂,为什么要这样做,很多情况下都是客户基于高级安全的需求,到底什么样的安全需求要这样一个配置,使用NAND FLASH的存储容量完全够满足程序的要求,无需要NOR FLASH的存在的理由啊,经过深入的理解后我知道了其中的缘由,我先把原因说了,后面我们慢慢说说FLASH的内部架构。

1.nor的成本相对高,具体读写数据时候,不容易出错。总体上,比较适合应用于存储少量的代码。

2.Nand flash相对成本低。使用中数据读写容易出错,所以一般都需要有对应的软件或者硬件的数据校验算法,统称为ECC。由于相对来说,容量大,价格便宜,因此适合用来存储大量的数据。其在嵌入式系统中的作用,相当于PC上的硬盘,用于存储大量数据。

所以,机顶盒常见的应用组合就是,用小容量的Nor Flash存储启动代码,比如uboot,系统启动后,初始化对应的硬件,包括SDRAM等,然后将Nand Flash上的Linux 内核读取到内存中,做好该做的事情后,就跳转到SDRAM中去执行内核了,然后内核解压(如果是压缩内核的话,否则就直接运行了)后,开始运行,在Linux内核启动最后,去Nand Flash上,挂载根文件,比如jffs2,yaffs2等,挂载完成,运行初始化脚本,启动consle交互,才运行你通过console和内核交互。至此完成整个系统启动过程。而Nor Flash存放的是Uboot,Nand Flash存放的是Linux的内核镜像和根文件系统,以及余下的空间分成一个数据区。

1、NAND FLASH的基本介绍

上图是FLASH的存储原理,采用Floating Gate存储数据的技术,存储电荷的多少,取决于图中的外部门(external gate)所被施加的电压,其控制了是向存储单元中冲入电荷还是使其释放电荷。数据的表示,以所存储的电荷的电压是否超过一个特定的阈值Vth来表示。

其实这里就很简单,就是通过一个存储的电荷是否超过阈值Vth来判定高低电平。想想法律怎么判断是否具有完全行为民事行为人,年龄是一个很重要的标志,判断你是否满了18岁。

看到这里,吃瓜群众会问,机哥,这里的存储是不是只有0和1呢,那我们从淘宝上看到有一些TF卡写 SLC、MLC、TLC是什么意思和差别呢。

Nand Flash按照内部存储数据单元的电压的不同层次,也就是单个内存单元中,是存储1位数据,还是多位数据,可以分为SLC、MLC、TLC。

1. SLC,Single Level Cell:

单个存储单元,只存储一位数据,表示成1或0.

就是上面介绍的,对于数据的表示,单个存储单元中内部所存储电荷的电压,和某个特定的阈值电压Vth,相比,如果大于此Vth值,就是表示1,反之,小于Vth,就表示0.

对于nand Flash的数据的写入1,就是控制External Gate去充电,使得存储的电荷够多,超过阈值Vth,就表示1了。而对于写入0,就是将其放电,电荷减少到小于Vth,就表示0了。

2. MLC,Multi Level Cell:

与SLC相对应,就是单个存储单元,可以存储多个位,比如2位,4位等。其实现机制,说起来比较简单,就是,通过控制内部电荷的多少,分成多个阈值,通过控制里面的电荷多少,而达到我们所需要的存储成不同的数据。

比如,假设输入电压是Vin=4V(实际没有这样的电压,此处只是为了举例方便),那么,可以设计出2的2次方=4个阈值,1/4的Vin=1V,2/4的Vin=2V,3/4的Vin=3V,Vin=4V,分别表示2位数据00,01,10,11,对于写入数据,就是充电,通过控制内部的电荷的多少,对应表示不同的数据。

对于读取,则是通过对应的内部的电流(与Vth成反比),然后通过一系列解码电路完成读取,解析出所存储的数据。这些具体的物理实现,都是有足够精确的设备和技术,才能实现精确的数据写入和读出的。

同理TLC也是一样的道理,只是单个存储单元可以存储3位数据的,称作2的3次方=8 Level Cell。

这个其实可以这样简单理解一下,SLC好比把你的学费给你分为两笔,一笔是18岁以前,一笔是18岁以后,每次都是10W元,那么你可以拿到20WRMB,MLC就分的更精细一些,小学、初中、高中、大学四个阶段来划分,每个阶段依旧是10WRMB,那么你可以拿到40WRMB。想想你自己就是一个存储器件,拿到的钱越多,代表存储的数据也就更多。当然一个人的表现差距不大,如果是一个班级,一个学校,那么总的汇总差距就大了去了。

那既然这样,为什么还要造SLC的FLASH呢,TLC存储容量大这么多,其实你想想FLASH的擦写寿命也就是在于无法充满电的风险,因为放电其实很容易,如果你等级划分的越多,越容易导致某个层级电压无法精细化满足,寿命也就没有那么久,而且读取的时间也会变长。

2、NAND FLASH的物理架构层分析

在讲解NAND FLASH的架构之前,我们先来看看图书馆。大家都去过图书馆吧,去图书馆找书一般是怎么找,先去不同的楼层,因为不同的楼层的书籍大概范围是不同的,哲学,化学、人文、小说都分布在不同的楼层,然后在根据书架上的分类,有的还是按年代,有的是按国籍进行的分类,然后再书架上找对应的书。

上图是我们公司常用的镁光 NAND FLASH MT29F1G08ABAEAH4:E的datasheet中的描述。

我们结合上面图书馆的书进行一下有趣而且比较容易理解的解释:

一个FLASH可以理解为一个图书馆,我们看图书馆的藏书有多少(假定都藏书都是红楼梦和西游记,代表数据的0和1),藏书越多多就代表这个FLASH的容量也大,每一本书代表着一个Byte数据的容量大小。

1.一个nand flash由很多个块(Block)组成,这里的block对应的图书馆就是有多少层楼,你想想层数越多,藏书肯定也就越多,这里的镁光NAND FLASH有1024个Block,意味着这个图书馆有1024层,四川话来说:楼层确实有点高,帽儿都望掉了。

2.每个块里面又包含了很多页(page)。这里就相当于图书馆一个楼层有多少个房间,这里的镁光Flash 一个block有64 页,也就是一个楼层有64个房间。

3.每一页的数据大小就相当于有多少一个房间里面有多少本书,这里看到镁光的规格书写的是1page=(2K+64)byte。

大家都去过图书馆看到过小书架吧,在3个大的书架前面会有一个小书架,用来放置一些找不到归还位置的书,等工作人员进行后续整理归还。

每一个页,对应还有一块区域,叫做空闲区域(spare area)/冗余区域(redundant area),而Linux系统中,一般叫做OOB(Out Of Band),这个区域,是最初基于Nand Flash的硬件特性:数据在读写时候相对容易错误,所以为了保证数据的正确性,必须要有对应的检测和纠错机制,此机制被叫做EDC(Error Detection Code)/ECC(Error Code Correction,或者Error Checking and Correcting),所以设计了多余的区域,用于放置数据的校验值。

这里的多余的数据是ECC数据,专门NAND FLASH是用做来校验正常数据的,因为FLASH的特性决定了数据容易造成翻转,本来这个位置写进去的是1,External Gate不小心进行了放电,此时读出来的是0了,此时就需要有纠正措施,后面有机会专门来介绍这个ECC校验的原理。

硬件一般支持的是512字节数据,对应有16字节用来存放校验产生的ECC数值,而这512字节一般叫做一个扇区。对于2K+64字节大小的页来说,按照512字节分,分别叫做A,B,C,D区,而后面的64字节的oob区域,按照16字节一个区,分别叫做E,F,G,H区,对应存放A,B,C,D数据区的ECC的值。所以规格书中经常会看到以下的信息,就知道后面的是OOB区域。

这里就用图书馆的理解就是,每一个房间有4个大书架,每个大书架有512本书就会后面放一个小书架,小书架可以放置16本登记本(这个本子用来登记这512本书的,防止书出现错误),这样算下来一个房间有2048本有用的书,同时有64个登记本。

在一个块内,对每一个页进行编程的话,必须是顺序的,而不能是随机的。比如,一个块中有128个页,那么你只能先对page0编程,再对page1编程,。。。。,而不能随机的,比如先对page3,再page1,page2.,page0,page4,.。。。

3、NAND FLASH的一些读写特点

刚刚说了,咱们这个图书馆有1024层楼,每层楼有64个房间,每个房间有2048本有用的书,还有64本用来记账校验的书。

这个图书馆的的馆长是一个老头,记性不太好,如果你要借第950层中第2个房间中的第10本书,馆长肯定不记得是红楼梦(代表数据0)还是西游记了(代表数据1)。

此时馆长就会给你这样操作,你直接把950层的第2个房间的书全部打包都借给你,你自己拿回去看第10本是什么书,虽然你很不情愿,但是没有办法,要知道这个房间里面的第几本书是什么,就必须全部房间里面的书都借出来。

还记得咱们说过一个房间里面有4个书架,每个书架有512本书,若要知道读取第二个书架上的第一本书是什么内容,上图的架构就是NAND Flash的电气连接方式。NAND Flash 的连接方式为串联,若要读取上图黄色 Word Line (字线)的数据,需对其他所有 Word Line 进行增加电压,加压后漏极和源极处于导通状态,也就是要知道上图红色方框中的数据,需要把蓝色方框的数据都导通才行。因此 NAND Flash读取数据的最小单位是页(即Word Line 上的所有数据),无法直接运行程序,所有数据必须先读取到 ARM 上后才可运行。

我们再来看看其他存储设备的读取的特点,N0R Flash 的连接方式为串联,读取数据不需对 Word Line 进行加压,直接测量对应的 Bit Line 和 Source Line 之间的通断即可获取该存储单元的数据。不仅实现了位读取,还大大提高了数据读取的速度。实现位读取,程序便可在 NOR Flash 上运行,即所谓的芯片内执行(XIP)。

为什么NAND FLASH不能XIP片内执行

1、 理论上是可以的,而且也是有人验证过可以的,只不过由于nand flash的物理特性,不能完全保证所读取的数据/代码是正确的,实际上,很少这么用而已。因为,如果真是要用到nand flash做XIP,那么除了读出速度慢之外,还要保证有数据的校验,以保证读出来的,将要执行的代码/数据,是正确的。否则,系统很容易就跑飞了。

2、 NAND FLASH每次读取出来的数据都是以页为单位,你想想,老师要你背诵语文书中的课本,每次你都直接丢给老师一本书,背诵的是目录,这个怎么可以直接算背诵呢。

咱们前面说了读数据,有人说写数据就简单了吧,就跟下五子棋一样,下黑棋还是白棋都只要往里填就行,不就是搭积木,往对应的位置写0或者1就行了吧,这个对于NOR Flash或者硬盘等操作,确实是这样的一个操作。NAND FLASH还稍微有一些特殊。

Flash的擦除操作是以block块为单位的,与此相对应的是其他很多存储设备,是以bit位为最小读取/写入的单位,Flash是一次性地擦除整个块:在发送一个擦除命令后,一次性地将一个block,常见的块的大小是128KB/256KB。。,全部擦除为1,也就是里面的内容全部都是0xFF了,由于是一下子就擦除了,相对来说,擦除用的时间很短,可以用一闪而过来形容,所以,叫做Flash Memory。中文有的翻译为(快速)闪存。

这里可以理解为某一天要进行图书馆的第10楼的第二个房间进行编程,也就是装修,此时图书馆馆长就命令人把10楼的书全部更换为西游记(全部擦除为1),然后要编程的时候,就把要从1变为0的地方更换为红楼梦而已,这样速度就非常快。

吃瓜群众:机哥,按照你的意思,那NAND FLASH编程是1变为0咯,那是不是也可以从0变为1呢?

NAND FLASH的编程是1变为0,物理上来说,是可以实现每一位的从0变成1的,但是实际上,对于实际的物理实现,出于效率的考虑,如果对于每一个存储单元都能单独控制,即0变成1,就是对每一个存储单元单独去充电,所需要的硬件实现就很复杂和昂贵,同时所进行对块擦除的操作,也就无法实现之前的,一闪而过的速度了,也就失去了Flash的众多特性了。在写数据之前,要先擦除,内部就都变成0xFF了,然后才能写入数据,也就是将对应位由1变成0。

可以看到NAND Flash和普通存储设备在读写方面操作是有一些比较大的区别,主要是读写的最小单位,擦除的最小单位,最重要的一点就是NAND Flash在写数据之前,一定要先擦除,然后才能写。

使用nand scrub命令的工程师要注意了

Nand Flash中,一个块中含有1个或多个位是坏的,就成为其为坏块。坏块的稳定性是无法保证的,也就是说,不能保证你写入的数据是对的,或者写入对了,读出来也不一定对的。而正常的块,肯定是写入读出都是正常的。

其实就相当于图书馆的某个楼层出现了问题,这个楼层就不能进行图书的保存,正常情况下也有两种情况下出现问题,一种是图书馆修好的时候就知道是坏的楼层,此时交付的时候就标记好,这个楼层在后面使用的过程中就不放置图书,还有一种情况下就是使用的过程中年久失修导致损坏,这个时候常见的做法就是把这个楼层的书搬离到还没有使用好的楼层里面去,同时把这个楼层标记为不能使用的楼层。

同理NAND Flash的坏块也有两种:

(1)一种是出厂的时候,也就是,你买到的新的,还没用过的Nand Flash,就可以包含了坏块。此类出厂时就有的坏块,被称作factory (masked)bad block或initial bad/invalid block,在出厂之前,就会做对应的标记,标为坏块。

具体标记的地方是,对于现在常见的页大小为2K的Nand Flash,是块中第一个页的oob起始位置的第1个字节(旧的小页面,pagesize是512B甚至256B的nand flash,坏块标记是第6个字节),如果不是0xFF,就说明是坏块。相对应的是,所有正常的块,好的块,里面所有数据都是0xFF的。

(2)第二类叫做在使用过程中产生的,由于使用过程时间长了,在擦块除的时候,出错了,说明此块坏了,也要在程序运行过程中,发现,并且标记成坏块的。具体标记的位置,和上面一样。这类块叫做worn-out bad block。

对于坏块的管理,在Linux系统中,叫做坏块管理(BBM,Bad Block Managment),对应的会有一个表去记录好块,坏块的信息,以及坏块是出厂就有的,还是后来使用产生的,这个表叫做 坏块表(BBT,Bad Block Table)。在Linux内核MTD架构下的Nand Flash驱动,和Uboot中Nand Flash驱动中,在加载完驱动之后,如果你没有加入参数主动要求跳过坏块扫描的话,那么都会去主动扫描坏块,建立必要的BBT的,以备后面坏块管理所使用。

而关于好块和坏块,Nand Flash在出厂的时候,会做出保证:

1.关于好的,可以使用的块的数目达到一定的数目,比如三星的K9G8G08U0M,整个flash一共有4096个块,出厂的时候,保证好的块至少大于3996个,也就是意思是,你新买到这个型号的nand flash,最坏的可能,有3096-3996=100个坏块。不过,事实上,现在出厂时的坏块,比较少,绝大多数,都是使用时间长了,在使用过程中出现的。

2.保证第一个块是好的,并且一般相对来说比较耐用。做此保证的主要原因是,很多Nand Flash坏块管理方法中,就是将第一个块,用来存储上面提到的BBT,否则,都是出错几率一样的块,那么也就不太好管理了,连放BBT的地方,都不好找了。而且如果只使用了NAND Flash没有配合NOR Flash的系统,uboot都是放到第一个块中,如果这个块损坏了,根本无法保障机器能够开机。像一些amlogic平台为了保险起见,就会把uboot拷贝在前面几个block中,当block 0无法启动的时候,该主芯片还支持从blcok 1启动,这个需要CPU内置程序代码才行。

就好比图书馆,你要去其他楼层,第一楼层得保障是好的吧,否则都没有办法乘坐电梯去其他楼层去了,是一个道理。

一般来说,不同型号的Nand Flash的数据手册中,也会提到,自己的这个nand flash,最多允许多少个坏块。就比如上面提到的,镁光 NAND FLASH MT29F1G08ABAEAH4,最多有100个坏块。

对于坏块的标记,本质上,也只是对应的flash上的某些字节的数据是非0xFF而已,所以,只要是数据,就是可以读取和写入的。也就意味着,可以写入其他值,也就把这个坏块标记信息破坏了。对于出厂时的坏块,一般是不建议将标记好的信息擦除掉的。

uboot中有个命令是“nand scrub”就可以将块中所有的内容都擦除了,包括坏块标记,不论是出厂时的,还是后来使用过程中出现而新标记的。一般来说,不建议用这个。最好用“nand erase”只擦除好的块,对于已经标记坏块的块,不擦除。

Nand Flash中的特殊硬件结构

由于nand flash相对其他常见设备来说,比较特殊,所以,特殊的设备,也有特殊的设计,所以,有些特殊的硬件特性,就有必要解释一下:

页寄存器(Page Register):由于Nand Flash读取和编程操作来说,最小单位是页,所以nand flash在硬件设计时候,就考虑到这一特性,对于每一片,都有一个对应的区域,专门用于存放,将要写入到物理存储单元中去的或者刚从存储单元中读取出来的,一页的数据,这个数据缓存区,本质上就是一个buffer,但是只是名字叫法不同,datasheet里面叫做Page Register,此处翻译为页寄存器,实际理解为页缓存,更为恰当些。

只有写到了这个页缓存中,只有等你发了对应的编程第二阶段的确认命令0x10之后,实际的编程动作才开始,才开始把页缓存中的数据,一点点写到物理存储单元中去。

今天讲了EEPROM、NOR、NAND FLASH的一些区别,在使用中需要注意的事项,下期内容总会重点讲解NAND FLASH的具体操作的文档解说,方便大家对于NAND FLASH的操作有更进一步的理解。

(0)

相关推荐