嵌入式系统中的线性Flash文件系统设计
进行碎片整理的方法可以有多种。对于嵌入式系统来说,选择哪种方法,衡量的依据是复杂性和功能之间的平衡。下面讨论两种不同的方法:第一种方法相当简单,但是有缺陷;第二种方法功能强大得多,笔者在线性文件实现中即采用这种方法。当然,存在更加复杂的解决办法,但通常的情况是,所添加的复杂性会使整个文件系统的实现更加复杂。目标是保持文件存储的简单和线性,保证所有的文件都是以连续的空间存储在Flash中。
最简单的方法是将活动的文件备份在RAM中,删除分配给文件系统的Flash空间,然后将RAM中备份的所有文件拷贝回Flash。这种方法很简单,并且不需要分配一个扇区作为空闲区;但问题是,需要有一整块和分配给文件系统的空间一样大的RAM来完成这项工作。更糟的是,如果此时系统被复位,或者在删除扇区内容却还没有将文件拷贝回Flash的时候被断电,文件系统将会崩溃。因为RAM中的内容会随之选择,文件内容会被破坏掉。
我们在文件系统实现设计了一种碎片整理方法,可以防止在碎片整理过程中系统复位导致文件崩溃的情况。采用这种方法,不需要大块的RAM,但是需要预选先分配给碎片整理过程一个Flash扇区作为备份区。这个扇区的字节数不小于任何分配给文件系统的扇区。在整个文件系统中,这个扇区位于分配给文件系统最后一个扇区的下一个扇区。因为扇区可能比需要分配给非删除文件的备份的空间要小,所以它必须逐个扇区进行处理,而不是一下就把所有的碎片整理完。采用备份扇区的好处是,在碎片整理过程中,无论断电或者复位都不会破坏文件系统。当下次系统重新恢复时,会根据在碎片整理前记录的每个扇区碎片整理前后CRC值,来判断当前的文件碎片整理状态。如果上次文件整理没有完成,就会继续上次的整理。这种技术的一个缺陷是空闲扇区的擦写次数会较多。这样空闲扇区就可能因为达到擦写寿命而失败。达到这一点的关键依赖于使用的Flash、所分配给文件系
统的扇区数、文件删除和重建的频率。一个可行的解决办法采用电池备份的RAM来替换空闲扇区,可以增加Flash的整体寿命,但是对那些预算紧张的应用来说太过奢移。
具体的碎片整理过程是,首先建立碎片整理区。①为每个扇区建立2个CRC32表项;第一个CRC32是这个扇区在碎片整理前的CRC值;第二个CRC32值是计算出来的碎片整理后的CRC32值。这些CRC是当碎片整理过程被打断时,用来重新恢复整理用的。②创建碎片整理文件头信息表,每个活动的文件占用一个表项。③计算①和②的CRC值,并保存。①~③的数据保存在图1中的碎片整理记录区。第二步是文件重定位;遍历文件系统的每个扇区,处理重新定位后存储空间和该扇区相覆盖的文件。在每个扇区被重写之前,扇区原来的信息被保存在空闲扇区里。第三步,擦除Flash;遍历未使用的扇区,确认所有的扇区被删除。第四步,完整性检测:对新的文件进行检测,保证所有重定位的文件都是完整的。
3 应用分析
Flash的扇区有最大擦写次数。当前的Flash芯片一般支持10万~100万次的擦除。文件系统的应用各不相同,所以这里不能下结论说采用线性文件系统Flash的寿命会有多长。下面解释文件系统访问Flash的方法。这样用户可以根据应用来判断Flash的预期寿命。
我们所设计的线性文件系统并不进行扇区删除次数均衡,以延长Flash的使用寿命。如果所需要的文件系统频繁修改并需要扇区删除次数均衡,可以购买现成的Flash文件系统。扇区删除均衡算法大大增加了底层实现的复杂性,并且超出本文的讨论范围。一般来说,通过文件系统来管理Flash的需求远大于对Flash扇区擦写次数均衡的需求,特别是现在越来越多的Flash扇区都支持100万次的擦写。
如上面所提到的,文件系统本身提供给编程者的接口API与标准OS提供的接口类似。这可能误导开发者认为文件系统可以看作是一个硬盘,以任意的频率进行读写操作。事实并不是这样,线性文件系统碎片整理同制并没有进行擦写次数均衡,这意味着空闲扇区可能会是最早损坏的Flash扇区。因为在碎片整理过程中,空闲扇区被用作其它所有扇区的暂时存放扇区。例如在设计里,有13个扇区Flash用来作线性文件系统区,有1个扇区作为空闲扇区。假设对于最坏情况的碎片整理(13个扇区都影响到),如果每天进行1次碎片整理,对于100 000次擦写次数的Flash而言,可用期能够超过20年(100 000/13/365=21)。20年是基于每天进行1次碎片整理,并且所有扇区都影响到的情况。碎片整理的频率和整理所影响到的扇区数受应用程序使用文件的限制。用户可以根据文件系统的应用来估算Flash扇区的磨损情况,并作相应的处理。
下面讨论文件系统是如何使用扇区的。Flash扇区仅仅在碎片整理时候才被擦除。当删除文件的时候,只是简单地作一个标识(文件头的一个位)。如果一个存在的文件以写的方式打开,实际的修改步骤是,删除原有的文件,并在
《嵌入式系统中的线性Flash文件系统设计(第3页)》