摘 要:NAND Flash具有高存储密度和高存储速率的特点,在嵌入式系统领域得到了广泛应用。但其固有的擦除机制和存在有坏块这一致命弱点,成为其在应用中的主要障碍。本文提出了一种应用于FAT文件系统上的坏块处理方法,使用Flash上其他的空闲块或者空闲空间来代替坏块,并将坏块在FAT表中作出标记以后不作使用。这种方法彻底屏蔽了坏块对上层应用的影响,并对存储介质没有造成任何不良影响,从而很好地克服了上述障碍。工程项目中的应用证明了其较高的可靠性。
随着嵌入式系统在消费电子,数据采集和工业控制等领域得到越来越广泛的应用。各个领域都对嵌入式系统提出了更高的要求。储存系统作为嵌入式系统中的重要组成部分,呈现出了较快的发展速度。随着各种应用对存储容量的要求不断增加,NAND Flash以高密度、大容量、高数据存储速率,以及更多的擦除次数等特点,逐渐成为大容量嵌入式存储设备应用的主流。而将FAT文件系统用于NAND Flash的嵌入式应用环境,由于其和Windows 操作系统良好的兼容性而成为现阶段若干工程应用中所使用的存储系统解决方案。但是由于工艺和使用环境的问题,NAND Flash存储器中不可避免的会出现坏块,以前也有过消除坏块的努力,但发现成品率太低,成本太高,根本不划算。所以必须在应用中进行坏块处理。本文提出一种应用于FAT文件系统的坏块处理方法,很好解决了坏块问题,实现了存储系统的高可靠性。
1 FLASH存储和文件系统简介
1.1 Flash 简介
Flash存储器是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何Flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。Flash存储器其内部分为若干个存储单元块(block) ,每个存储单元又分为若干个页(page),存储单元块是最小的擦除单位,页是写入数据的最小单位。Flash存储器读取数据类似于普通存储器可以实现随机读取,且读出速度也较快。而写入数据则相对比较麻烦,必须先按存储单元块擦除,即写入0xFF。再按页顺序写入。其中主要耗时在于擦除步骤。采用Flash存储器不得不重点考虑的问题在于可靠性,对于NAND Flash而言,每个块的最大擦除次数大约为一百万次, NAND Flash中的坏块是随机分布的,可能在出厂时就存在坏块,也可能于使用过程中出现坏块。
1.2 文件系统原理
文件系统在整个系统中位于设备驱动程序和上层应用程序之间,负责管理文件的创立、撤消、读写、修改、复制和存取控制等,并管理存放文件的各种资源。为上层引用程序提供统一的存储接口,透明具体的实现过程,为上层提供服务。它管理硬件上的数据存取方式和结构,以更好利用存储空间和提高存储效率。FAT文件系统是在微软DOS/Windows操作系统中广泛使用的一种文件系统,一个典型的FAT文件系统分区由4个部分组成: ①保留区;②FAT表区;③根目录区;④文件数据区。第一个扇区是BPB,即基本输入输出参数块,其上记录每扇区的字节数(512),每簇的扇区数,FAT表的数目,目录项数,总扇区数,FAT表占用的扇区数等文件系统的总体信息。然后是FAT表区,出于安全考虑一般存放两个FAT表。根目录区存放位于根目录的文件索引。所有的用户数据存放于文件数据区。
FAT将磁盘空间以一定的扇区数目划分为簇,通常情况下一个扇区512byte的原则是不会改变的,而簇则是由2n个扇区构成。簇的划分影响整体性能,较大的簇可以减少簇的数量,减小FAT表大小,提高系统性能,但是较大的簇对磁盘空间的利用率不高。较小的簇则正好相反。FAT文件系统存储原理:为每个文件创建索引链,链上元素是该簇所链接的下个簇号,或者文件结束标志。每一个文件都对应着1条簇链。操作系统读取或写入文件时,首先通过查找目录确定该文件的起始簇号,这个簇号就是这个文件的对应的索引链的首簇号,根据簇号在数据区读取或写入数据,然后通过查询FAT表项确定下一簇的簇号,直到文件结束,FAT表的表项中文件结束标志为FF。
从嵌入式系统的存储结构来看,可以将整个存储系统分为4层:如图1由底到高分别为硬件设备层;驱动层;文件系统;上层应用。上层为下层提供接口,下层为上层提供服务。
2 NAND Flash坏块处理
2.1 处理思想
NAND Flash的坏块问题是影响存储可靠性的重要问题,解决方式有2种,一种是在驱动层解决坏块问题,将不可靠的NAND Flash虚拟为一个可靠的存储设备,为上层文件系统提供可靠的透明的服务。第二种方法是在文件系统层解决,驱动层只实现其本身基本功能,文件系统为驱动层提供不变的接口,为上层应用程序提供可靠的透明的服务。两种方法各有优点,第一种方法具有较强的可移植性,由于FAT文件系统已经相对成熟,这种将坏块处理做在驱动层的方法,可以彻底断绝和文件系统的联系,不光适用于FAT文件系统,其他文件系统同样可以使用。但是由于坏块问题是一个相对复杂的问题,经过实践表明,在驱动层解决坏块问题所需要的资源,无论是CPU 资源还是存储资源都大幅增加,而且软件实现方式非常复杂。第二种方法实现方式较第一种方式简单,开发周期较短,对于特定应用的嵌入式系统具有更强的适应性。本文介绍的是第二种方法,一种在文件系统的底层解决坏块问题的方法,见图1,图2所示。遇到坏块则在FAT表中将相应的簇标记为不可用,以后不再使用,并寻找一个正常的空闲块来代替它,如果没有空闲块,则寻找相应数量的空闲簇来组合代替。
2.2 具体实现方法
把FAT表中的文件簇链看作链表,可以在文件系统初始化过程中在内存里建立文件系统的反向簇链,方便进行坏块的替换。写入数据时,由于NAND Flash在写入前必须先进行擦除,擦除的最小单位为1个block,大多数NAND Flash是32个page为1个block,因此要在内存中申请1个block大小的内存空间,作为缓冲区,首先将要写入数据page所在的block全部读入缓冲区,然后在缓冲区中找到相应page把数据写入缓冲区,对该block数据写完后,再将缓冲区中的数据全部写入Flash,整个写入过程是一个先擦除再写入的过程,若在写入过程中发生多次错误,就确定该块为坏块,进入坏块处理程序(图3) 。
坏块处理程序中首先备份坏块对应簇的FAT表项,保存在一数组中,然后将该簇其标记为坏(0xFFF7) ,寻找替代块。
(1) 替代块算法 首先从Flash的末尾开始,以块为单位,寻找空闲块,所谓空闲块,就是其包含的所有簇都是空闲状态。找到就进行整块替换。具体替换方式和替换簇算法一同解释。如果一直寻找到数据区开头都没有,则寻找替代簇。
(2) 替代簇算法 找替代簇不同于替代块之处在于,替代簇并不一定在物理上是一段连续空间,其实际效率也不如连续存储的效率,因此其在没有替代块的时候才采用,其FAT表项的链接方式也比替代块复杂。根据坏块处的链接不同,执行不同的替换算法。假设将簇的大小定为8个page,则一个block包含4个簇。坏块示意图如图4所示,第N 簇至第N + 3 簇为坏块所在区域,a,b,c,d 这4个簇分别是它们相应的替换簇。在每一簇替换过程中分为3种情况: ①坏簇所链接的下一簇不在坏块范围中。②该坏簇链接的下一簇在坏块范围里,且位于当前簇的前面; ③该坏簇链接的下一簇在坏块范围里,且位于当前簇的后面。第一种情况就直接替换,将备份的索引号,直接赋值给新簇对应的FAT表项,同时更新反向FAT表。第二种情况由于其指向的簇在之前已经被替换,所以要在前面更新FAT表时对替换的新簇簇号进行备份,根据两坏簇之间的相对位移,到替换簇号记录中查找之前替换掉新的簇号来更新当前簇的链接,同时更新反向FAT表。第三种情况,位于后面的簇也是坏簇,且替换位置未知,所以则此时只更新反向FAT表,其本身的FAT表项等待更新坏簇的前续节点时再做更新。最后查询反向FAT表将新替换的各个簇接回其前续节点。
2. 3 伪代码
for (i = 0 ;i < 4 ;i + + )
{ //处理坏块中的第i + 1 个簇
replace[ i ] = 用来替换当前坏簇的簇(a ,b ,c ,d) ;//repalce数组中保存各个用来替换的簇簇号。
x = replace[ i ] ;
If (fat (N + i) < N || fat (N + i) > N + 3)
{
/*该坏簇链接的下一簇不在坏块范围内,fat( )表示对应FAT表项*/
fat (x) = fat (N + i) ;
vfat (fat (N + i) ) = x ;//vfat()表示对应的反向FAT表表项。
}
else if (fat (N + i) < N + i)
{
fat (x) = replace[fat (N + i)2N ] ;//查询之前的替换记录确定当前簇的下一个节点。
vfat ( replace[fat (N + i)2N]) = x ;//更新反向FAT表。
}
else if (fat (N + i) > N + i)
/*该簇链接的下一簇在坏块范围,且位于当前簇之前*/
/*由于后面的簇替换簇还未知,所以只更新反向表,待确定了之后在接回前续。*/
vfat (fat (N + i) = x ;
if (vfat (N + i) < N| | vfat (N + i) > N + 3)
/*前续节点不位于坏块内这种情况是唯一的一种需要单独处理的前续节点问题,其他的情况由于前续节点也位于坏块内,在上面就已经完成了*/
{
fat (vfat (N + i) ) = x ;
vfat (x) = vfat (N + i) ;
}
}
以上3种情况在使用替代块(图5)时同样存在,只是相对简单,在第二种情况中替代块算法由于找的替代块是一些空间连续的簇,因而后面的簇的替换簇已知,因而不用在备份前面的各替代簇号,可以直接使用簇之间的偏移量来确定。
图5 替代块
如果FAT表中已经没有空闲簇则报错,完成以上的替代算法后,可以实现把坏块在写入数据时自动屏蔽,并记录于FAT表中,即使对使用过程中出现的坏块也可以在对该块进行写入操作时,将其标记出来,并将数据写入替代的空间。使得NANDFlash的可靠性大为改善。
2.4 可靠性测试
在测试中,使用一块16M的NAND Flash进行测试,对其进行全容量的反复读写,测试时间约为1星期,测试代码实现先写入一块数据然后读出校验的实现方法,在没有采用坏块处理程序之前由于其坏块的存在导致写入的文件在大约6M之后全部丢失,采用坏块处理程序之后,运行的一周内没有任何校验错误。由此可见其可靠性得到很大提升。
3 结论
对NAND Flash的坏块进行处理是所有使用NAND Flash作为存储介质的嵌入式系统都必须面临的问题,本文的处理方法很好的解决了在NANDFlash存储介质上运用FAT文件系统的坏块问题,增加了整个嵌入式系统的存储可靠性。
作者:罗晓,刘昊(东南大学国家专用集成电路系统工程中心,南京210096)
参考文献:
[1]陈育智,嵌入式系统中的Flash 文件系统[J].单片机与嵌入式系统应用,2002,(2):528.
[2]骆丽译. 嵌入式系统设计[M],北京航空航天大学出版社.
[3]陈代军,解析FAT文件系统对长文件名的支持[J].成都信息工程学院学报,18 :3802385.
[4]Jeff Child. Flash Memory Evolves for Post2PC Era Applica2tions ; Embedded Syst . dev. 1999.
[5]Information Technology2Small Computer System Interface22[S]ISO/ IEC9316 :1995211202.
[6]Microsoft Extensible Firmware Initiative FAT32 File SystemSpecification[EB/OL]. rev.1.03,2000212206.
[7]Samsung NAND Flash Memory [S] , Memory Product & Technology Division ,March 2000.
[8]Seiichi Aritome , Riichiro Shirota , Gertjan Hemink. ReliabilityIssues of Flash Memory Cells[J].IEEE. May 1993.81(5).