英创工控主板FAT文件系统的稳健读写方法

 2013-5-14         

        在基于WinCE的嵌入式系统中,通常NandFlash + FAT文件系统是最为常用的数据存储方式。对这类设备长期运行情况的跟踪,我们发现在一定的应用情况下,FAT文件系统存在失效的可能,而文件系统的失效导致系统在重启中不能读取系统注册表或应用程序文件,宏观的现象就是设备不能正常运行。

 

        经过对FAT文件失效情况的分析,我们发现出现失效的系统往往有以下两种文件操作:

        1、需要保存运行日志文件,每条日志记录大约两百字节水平,整个日志文件可包含上万条记录,即日志文件大小在2MB水平。应用程序对日志的操作是随机的。

        2、系统有一个容量上兆的配置文件,应用程序可能根据运行的情况,动态修改配置的内容。

 

        以上这两种文件操作,对NandFlash + FAT的存储单位,由于文件都比较大,都可能导致大规模的NandFlash块擦除及数据搬动。当此时CPU负载还比较重时,FAT文件系统内部的某种缺陷就可能暴露出来,从而危害设备的稳定运行。

 

        针对上述两种应用的特点,以规避FAT文件系统出现致命缺陷为目的,我们设计了一层新的文件操作API函数,来替代常规的文件API函数。新的API包括以下6个函数:

          HANDLE CreateFileEm(……); 
          BOOL ReadFileEm(……); 
          BOOL WriteFileEm(……); 
          DWORD SetFilePointerEm(……); 
          DWORD GetFileSizeEm(……); 
          BOOL CloseHandleEm(……);

 

        这6个API函数的名称与对应的常规函数名称基本一致,只是在末尾增加了“Em”两个字母以示区别,函数的参数与常规函数的参数则完全一致。应用程序只需做简单的修改,就可使用我们所提供的新方法。

 

        新的文件操作的要点,是把一个日志文件或配置文件,映射为NandFlash下的子目录,文件的内容则分成若干个子文件(以下称为量子文件,以表示它的不可分割性),量子文件按序号0000依次递增9999,每个量子文件的大小为NandFlash的扇区大小,在英创工控主板中NandFlash的扇区Size为2KB,当前量子文件写满2KB后,会自动生成当前序号+1的新量子文件。API内部建有当前量子文件的数据缓冲区,当读写仅限于当前量子文件大小(即2KB)时,不会产生实质性的NandFlash读写,从而降低NandFlash的读写负担。即使进行实质性的写操作,因为总是2KB,FAT文件系统的工作量也被降到最低。

 

        新的API函数尽管可支持不同线程操作同一文件,但若出现不同线程对同一个量子文件进行读写操作,则可能存在数据丢失的情况、读取的数据不是最新数据的情况。因此应用程序应尽量避免不同线程对同一个量子文件进行读写操作。

 

        在200MHz主频的CE5.0系统中(如 EM9160、EM9360等),新API函数的文件写操作的平均速度在90KB/s – 95KB/s范围,文件读操作的平均速度在600KB/s – 700KB/s范围。

 

        一般情况下若写入的数据处在一个量子文件大小区域内,为了提高NandFlash的操作效率,不会立即触发实质性的NandFlash写。但之后一定时间内(设置为2秒),没有进一步的写操作,新API的后备线程会自动把应用程序写入的数据实质性写入NandFlash的对应量子文件中。因此这里存在,在实质性写入发生之前,系统由于某种情况出现重启(Power Cycling),应用程序写入的数据就会丢失的情况。这是为避免致命性错误,应用程序需付出的代价。

 

        更极端的情况,当正在实质性写某一量子文件时,系统出现Power Cycling,还可能存在该量子文件被破坏的情况。但这种情况在常规写中同样存在,且被破坏的还是整个文件。因此新API是Power Cycling对整个数据的损坏度是降低了的。

 

        更重要的是,在系统进入稳定运行后,量子文件的数目瞬间不会有大的变化,甚至完全没有变化(配置文件情形,或日志文件达到应用程序设置的上限),这样新的API对FAT文件系统的FAT表、目录区的负载会降到最低,从而大大避免FAT文件系统的关键区域被Power Cycling破坏的可能性。这是新API规避FAT文件系统缺陷的关键所在。

 

        新API的定义包含在“LogFile.h”头文件中,具体实现代码则在“LogFile.cpp”中,对客户应用程序,只需简单的把LogFile.cpp加入到应用程序中,并在相关的cpp文件中include头文件LogFile.h,就可方便的测试评估该方法了。

 

        欢迎客户反馈使用中的情况至:support@emtronix.com