一、Nand/Nor Flash简介

NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,1989年,东芝公司发表了NAND flash结构,强调降低每比特的成本,提供更高的性能,并且像磁盘一样可以通过接口轻松升级。其容量可达1GB以上,并且写入和擦除速度很快,更适合于数据存储。

NOR Flash的存储单元位块(block),一般每个块64K~128K,块也是擦除的单位。

NAND Flash的存储单元为页(page)和块(block),块仍然是擦除单位,页作为坏扇的管理单位。每个块内包含若干个页,通常是32页,每个页又分为主数据区和附加数据区(extra),如果主数据区出现EDC/ECC校验错误,可以把错误记录在附加数据区。主数据区和附加数据区使用不同的命令字读/写,所以,从外界看来,主数据区和附加数据区具有相同的起始地址。常见的页的大小有两种,一种页的大小为512字节(简称“小页”),物理上依次分为2个256字节的主数据区,最后是16字节的备用空间(spare),“小页”模式多用于小于128M的芯片;而128MB以上的芯片大多使用大小为2K的页(即“大页”),附加数据区也不再是16字节,而是2048字节。

性能比较

flash闪存是非易失存储器,可以对存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。NOR器件的擦除单位比较大,一般是以64~128KB的块进行,执行一个擦除操作的时间为秒级,一般在1~3秒; NAND器件的擦除单位相对NOR要小,一般是以8~32KB的块进行,执行相同的操作最多只需要4ms。NOR的读速度比NAND快的多。对NOR器件的读不需要做地址的特殊映射,可以把NOR Flash当作内存直接读取。NAND的写入速度比NOR快的多。NAND的4ms擦除速度远比NOR快。

接口差别

NOR flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。可以非常直接地使用基于NOR的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。NAND器件使用复杂的I/O口来串行的存取数据,各个产品或厂商的方法可能各不相同。8个引脚用来传送控制、地址和数据信息。NAND读和写操作采用512字节的块,这一点有点像硬盘管理此类操作,很自然地,基于NAND的存储器就可以取代硬盘或其他块设备。

由于需要I/O接口,NAND要复杂得多。在使用NAND器件时,必须先写入驱动程序,才能继续执行其他操作。向NAND器件写入信息需要相当的技巧,因为设计师绝不能向坏块写入,这就意味着在NAND器件上自始至终都必须进行虚拟映射。

容量和成本

NAND flash的单元尺寸几乎是NOR器件的一半,由于生产过程更为简单,NAND结构可以在给定的模具尺寸内提供更高的容量,也就相应地降低了价格。

NOR flash占据了容量为1~16MB闪存市场的大部分,而NAND flash只是用在8~128MB的产品当中,这也说明NOR主要应用在代码存储介质中,NAND适合于数据存储,NAND在CompactFlash、Secure Digital、PC Cards和MMC存储卡市场上所占份额比较大。

可靠性和耐用性

采用flash介质时一个需要重点考虑的问题是可靠性。对于需要扩展MTBF的系统来说,Flash是非常合适的存储方案。可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性。

寿命(耐用性)

在NAND闪存中每个块的最大擦写次数是一百万次,而NOR的擦写次数是十万次。NAND存储器除了具有10比1的块擦除周期优势,典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储块在给定的时间内的删除次数要少一些。

位交换

所有flash器件都受位交换现象的困扰。在某些情况下,一个比特位会发生反转或被报告反转了。NAND发生的次数要比NOR多。如果只是报告有问题,多读几次就可能解决了。,如果这个位真的改变了,就必须采用错误探测/错误更正(EDC/ECC)算法。位反转的问题更多见于NAND闪存,NAND的供应商建议使用NAND闪存的时候,同时使用EDC/ECC算法。

这个问题对于用NAND存储多媒体信息时不是致命的。当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时,必须使用EDC/ECC系统以确保可靠性。

坏块处理

NOR不存在坏块问题,所以NOR的驱动中都不考虑坏块处理。NAND器件中的存在坏块,坏块随机分布。以前也曾有过消除坏块的努力,但发现成品率太低,代价太高。到目前为止还没有有效的方法彻底消除。NAND器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用。在已制成的器件中,如果通过可靠的方法不能进行这项处理,将导致高故障率。

二、VxWorks现存的支持方式

在vxworks_kernel_programmers_guide_6.6.pdf里面对TFFS的描述如下:

Including the Translation Layer Component, Choose the translation layer appropriate to the technology used by your flash medium. The main variants of flash devices are NOR and NAND. TrueFFS provides support for:

  • NOR devices.
  • NAND devices that conform to the SSFDC specification.

从对Nand部分的描述来看,只支持符合SSFDC标准的Nand Flash器件。历史上,vxWorks5.4曾经支持过NFTL的Translation Layer。后期的版本中不知道处于什么目的不再支持。无论是NFTL还是SSFDC,都支持的是“小页”模式。

顺便提一下,在linux里,YAFFS支持“小页”模式,YAFFS2和JFFDS2支持“大页”模式。

下面两节中将分别针对NFTL和SSFDC做单独的讨论。

三、SSFDC

SSFDC的概念起源于SM(SmartMedia)卡,这是由东芝公司在1995年11月发布的Flash Memory存贮卡,三星公司在1996年购买了生产和销售许可,这两家公司成为主要的SM卡厂商。为了推动SmartMedia成为工业标准,1996年4月成立了SSFDC论坛(SSFDC即Solid State Floppy Disk Card,实际上最开始时SmartMedia被称为SSFDC,1996年6月改名为SmartMedia,并成为东芝的注册商标)。SSFDC论坛有超过150个成员,同样包括不少大厂商,如Sony、Sharp、JVC、Philips、NEC、SanDisk等厂商。

SSFDC定义了一套严格的标准,包括硬件规格、软件设计、电器特性等等,具体的内容可以到SSFDC论坛下载。

SSFDC的标准与普通的Nand差别不大,都是主数据区加附加数据区的模式,对软件产生映象的是它对块大小的定义。

当Flash大小小于2M的时候,每个Sector包含了两页;当Flash大小在4M到16M之间的时候,每个Sector包含一页;大于32M的时候,每32M作为一个Zone管理。

在vxWorks缺省的代码中不支持Zone,最大只能支持16M。可以在config.h里面增加宏INCLUDE_TL_SSFDC或者在IDE环境中使能相应的组件。

SSFDC对Flash大小的限制在代码中体现在下面两点,如果对SSFDC足够熟悉,可以自行修改使之支持更大的Flash空间。

1、formatSSFDC和mountSSFDC中对大小的判断。

在上述两个函数中都对可管理的Unit总数做了限定,如下面这段代码。这段代码在两个函数中都存在。

vol.virtualSectors = vol.sectorsPerUnit;

if (vol.noOfUnits < 500)
    vol.virtualSectors *= 250; /* 1 MByte chip */
else if (vol.noOfUnits < 1000)
    vol.virtualSectors *= 500; /* 2 or 4 MByte chip  */
else
    vol.virtualSectors *= 1000; /* 8 0r 16 MByte chip */

其主要的意图在于,限定可管理的Unit个数不超出1000,因为在Spare区给出的BlockAddress只有两个字节,虽然BlockAddress有两部分,但是按照SSFDC的规定,这两部分是备份关系,不能一起用。并且在这两个字节共16位中除去状态位只有10可用,也就是说,理论上block只能寻址1024个block,当block数目大于1024时,将出现Unit重复。

2、physical2Virtual对地址的判断。

physical2Virtual是SSFDC中负责地址翻译的函数,这个函数中对地址的处理“粗”了一个比特,按照标准,这里应该使用1到10比特,共10个位表示1024个值。但我们的代码中少移了一位,做成了11位,所以在formatSSFDC和mountSSFDC中增加一个vol.virtualSectors *= 2000是不需要修改其他内容就可以运行的。

如果要支持更大的空间,必须对下面的移位操作做处理,按照标准,用于地址的16个比特,除了最低位(即0比特)用于状态外,其他位都是没有使用的。

static UnitNo physical2Virtual(SSFDC vol, UnitNo unitNo, int addressAreaNo)
{
。。。
/* virtual address is in bits 1 through 11 */
virtualUnitNo <<= 4;
virtualUnitNo >>= 5;
return virtualUnitNo;
}

四、NFTL

NFTL只在vxWorks5.4支持。要在产品中使用NFTL的Translation Layer,需要从vxWorks5.4移植。

首先,把Src\Tffs\nftllite.c拷贝到工程目录下,修改makefile使之能够编译。然后修改tffsConfig.c中的tlTable表,增加一项:

#ifdef
INCLUDE_TL_NFTL
#ifdef
FORMAT_VOLUME
{mountNFTL, formatNFTL},
#else
mountNFTL,
#endif /* FORMAT_VOLUME */
#endif /* INCLUDE_TL_NFTL */

Nand的驱动与Nor的不同,在Nand Flash驱动中需要多处理一些Flash读写的mode字段,这些字段在Nor Flash中可以忽略的。Mode在读/写函数中都会出现,有三种mode:EXTRA表示要读写的数据处于附加数据区(即Spare区);0表示读写的数据处于主数据区;EDC表示读写的数据在主数据区,但操作结束后需要对数据做EDC/ECC的校验,如果是写操作,还需要在附加数据区的第5、6字节写入0x5555。

NFTL对Flash大小的限制跟Nor一样是2047M,但是当Block数量比较多的时候,NFTL会自动把几个Block合为一个。这是因为大多数Nand Flash都保证第一、二个Block不会是坏块,NFTL需要把一些关键数据写在前两个Block,所谓的关键数据实际上只是对管理范围内每个Block的简单描述,每个Block在这里占用一个字节,前两个Block是备份关系,当Block的数量超过Block内字节数的时候,NFTL自动把两个Block合为一个。Nand Flash的NFTL的组织结构跟Nor Flash的FTL不同,FTL在每个Block的头部都有一个UnitHeader,里面记录了TFFS配置信息,只要找到任何一个就可以读出TFFS的全部配置。而NFTL的Block只用来记录数据,数据的属性等记录在各自的附加数据区。要想获取配置信息必须找到Nand Flash的第一个Block。