1 引言
随着嵌入式系统广泛应用,嵌入式系统中的数据存储和数据管理则成为设计人员考虑的重点。在许多现场不可达数据采集应用中采用分布式数据存储,必然带来数据管理的不便,因此,集中管理数据成为一种思路。利用成熟的网络传输技术集中分布式嵌入式系统数据,采用C/S模式管理数据。对于大容量数据存储,选择介质存储是需要重点考虑的问题。目前大多采用IDE硬盘或SCSI硬盘存储,但都存在抗震和抗电磁干扰能力差、使用温度范围窄,无法长期在恶劣的环境中长期工作。电子式Flash存储器具有速度快、容量大、成本低、体积小等优点,尤其能够在恶劣的环境下正常工作。随着NAND Flash容量不断增大,选择NAND Flash作为嵌入式数据存储已成为一种趋势。
本文以三星公司的K9T1G08U0M为例,设计了基于大容量NAND Flash的网络存储系统,该系统具有速度快、安全可靠、易扩展、抗震和抗干扰能力强、使用温度范围宽等特点,可方便的用于安全监控、生产数据记录、航行数据记录等方面,具有广阔的应用前景。
2 NAND Flash K9T1G08U0M
K9T1G08U0M是一块1 056 Mbit的NANDFlash存储器,262 144行(page)×528列,其存储结构如图1所示,其中512列至527列间是备用区。一个528字节的数据寄存器附在存储单元阵列用于页读取和页写入操作中I/O缓存和存储区之间数据传输,存储阵列由构成NAND架构的16个单元组成,16单元的每一单元都存放在不同的页中,一个块包含32页2个NAND架构。一个NAND架构包含16个单元,一个块中总共有8 448个NAND架构。写入和读取操作都是基于页的,但擦除操作是基于块的,存储阵列包含8 192个独立可擦除的16 KB块。这表明K9T1G08U0M中位擦除操作是禁止的。
K9T1G08U0M有8个复用I/O地址,减少了引脚数目并允许保持原系统板设计而使系统存储密度升级。命令、地址、数据都是在WE和CE控制下通过I/O写入。数据在WE上升沿锁存,命令和地址则是通过命令锁存允许(CLE)和地址锁存允许(ALE)区分,128 MB物理空间需求27位地址,因此需要4个字节地址周期:1个列周期,3个行周期。页读取和页写入都是在输入命令后紧跟着4个相同的地址周期。块擦除仅需要3个行周期。
3 NAND Flash编程特点
Flash主要有3种操作。Flash写操作可使存储单元由1变为0,存储单元为0后,不能再通过写操作置为1;Flash读操作不改变存储单元;Flash擦除操作可使存储单元由0变为1,但不能只对某个单元进行擦除操作。Flash的擦除包括块擦除和芯片擦除。块擦除是把某一擦除块的内容都变为1,而芯片擦除是把整个Flash的内容都变为1。通常一个Flash存储器可分为若干个擦除块。Flash存储时,是以擦除块为单位。当在一个块中存储时,一旦对某一块中的某一位写0后,若再要改变成1,则必须先对整个块进行擦除,然后才能修改。这点也是Flash最为麻烦的。通常,容量小的块操作过程:先将整个块存储到RAM中,在RAM中对其修改,再擦除整个块,最后写入修改值。显然,这样频繁复杂的操作将影响Flash的使用寿命和系统性能,而且系统无大容量RAM空间资源。
4 存储策略及实现
4.1 存储策略
在嵌入式网络存储应用中,首先考虑使用文件系统。文件系统必须保证数据完整性,也就是保证写入磁盘的数据与随后读取内容的一致性。目前在NANDFlash中使用的较多是日志文件,但日志文件系统为保障文件安全增加了额外的系统开销一每次更新磁盘节点,大多数“日志”操作是写同步,这就需要更多的磁盘I/O操作,而且日志文件系统更易产生碎片。
为了尽可能减少文件存储造成碎片空间的浪费,考虑到文件内容实际是一种二进制数据流,且对于有限的网络节点,并不需要频繁地建立、删除文件。设计人员只对近期的数据情况比较关心。因此系统可采用循环存储,即为每个文件指定存储空间。当存储空间即将耗尽的时候,最新的数据覆盖早先数据。这样可有效的避免产生额外Flash碎片。同时在磁盘可利用空间小于一定阈值时,可通过网络报警提醒用户处理Flash中的历史数据或采取相关措施。
由于NAND Flash具有一定的使用寿命,对于某一扇区的频繁读写将会严重影响Flash的使用寿命。因此可将Flash按流文件大小分块,通过循环存储避免Flash某些存储区域频繁的读写操作。当存储空间不足时,最新写入的数据覆盖早先的数据,这样既避免产生存储空间碎片也有效地延长Flash的使用寿命。
4.2 数据安全性考虑
4.2.1 无效块的管理
由于NAND Flash的工艺不能保证NAND的存储阵列在其生命周期中具有可靠的性能,因此,在NAND的生产及使用过程中会产生无效块。无效块的特性:当编程/擦除时,不能将某些位置高,以免造成页写入和块擦除操作错误,反映到状态寄存器相应位上,因此必须对无效块加以标识。
无效块总体上分为两大类:一类为固有无效块。该无效块是在生产过程中产生的,一般在出厂时,无效块第一页的备用区的第6个字节标记为非0xff的值。二类是使用无效块。在NAND Flash使用过程中,如果页写入或者块擦除错误。就可以简单地将这个块作为无效块,需将无效块作以标记。为了和固有无效块信息保持一致,需将该无效块的第一页的备用区第6个字节标记为非0xff。
NAND Flash出厂时在备用区已经反映了无效块信息,因此在擦除某一个块前,一定要先检查备用区的第6个字节是否为0xff,如果是0xff就证明为有效块,可擦除;否则该块就不能擦除。
为了对无效块管理。NAND Flash首块一定是有效块,在第0页中建立一张无效块表。对NANDFlash格式化时,需检测其原始无效块状态,将得到的原始无效块按块号大小顺序存入NAND Flash无效块表中。
如果在对一个块的某个页进行写入时产生错误,则将该块标记为无效块。首先要把其他页里面的内容备份到另外一个空闲可用块中。然后,标记此块为无效块,并将该块号以二分法算法插入无效块表中。为防止误判,可以在块备份完成后,再将该无效块擦除一次,如果块擦除错误,证明该块是真正的无效块。
4.2.2 ECC校验
Flash都存在位反现象,NAND Flash因注重于降低成本,位反现象比其他存储器更突出,而且数据存储应用对器件操作时可能由于电压不稳定等因素造成NAND操作错误。为尽可能减少错误,引入了软件ECC校验。此校验算法:把K9T1G08U0M的每一页分成4个512字节的数据区,4个对应的16字节备用区,每512字节数据采用ECC算法生成3字节的ECC校验码,存入相应备用区。数据读出后采用同样的算法生成新的3字节ECC校验码,对两次ECC校验码进行异或运算,根据结果做相应处理。这样可以检测和纠错一位数据,对于多位错误也可在应用程序中处理,可有效提高数据的可靠性,同时也为无效块检测提供依据。
4.3 实现
硬件系统采用带网络功能的Coldfire 5307最小系统+多片K9W8G08U0M,其硬件接口设计如图2所示。Coldfire 5307的高8位数据线和A24、A25通过74AVC16245分别作为K9W8G08U0M的I/O总线和ALE、CLE信号,WE和OE经7432逻辑变换后控制K9W8G08U0M的读、写。同时Coldfire的PP口用于扩展CS7的地址范围,片选K9W8G08U0M阵列。软件方面,在该平台上移植了μClinux,考虑到系统的主要任务是数据存储,因此将NAND Flash驱动程序直接置于μClinux内核,使其成为新系统调用,并把新系统调用源代码添加到μClinux-dist/linux/kernel/sys.c文件中,然后修改μClinux-dist/lin-ux/include/asm-m68nommu/unistd.h,给新系统调用分配一个系统调用号,修改μClinux-dist/linux/arch/m68knommu/platform/5307/entry.S,添加新的系统调用函数指针long symbol_name(sys_*),通知内核其他部分又增加了新系统调用函数。然后编译新的Linux内核,在应用程序中使用预编译宏指令sgscall调用相应操作。
应用程序基于socket编程,采用并发服务器模式,使系统能同时处理多个客户请求。服务器程序开始时调用socket()函数创建一个套接口,然后调用bind()函数将用户自定义端口捆绑到该套接口,并在程序中指定IP地址为INADDR_ANY,允许服务器接受任意IP地址客户的连接请求,通过调用listen()函数将此套接口转变成一个监听套接口,以监听连接到该端口上的客户连接请求。客户请求到达后,建立连接accept(),服务器调用fork()创建一个子进程为这个到达的客户提供服务,而父进程关闭已连接套接口,等待另一个客户的连接请求。在子进程中解析客户请求命令,根据命令进行存储、读取、擦除等操作。连接软件流程图如图3所示。
5 结束语
在嵌入式系统中实现NAND Flash的网络存储,可使分布式嵌入式系统的数据管理和用户管理集中在一个嵌入式服务器中,避免为了保存数据而必须采用的分散式用户管理,并有效降低整个系统成本。本系统经过随机数和文件的完整性系统测试,证实采用这种存储方式能够有效地完成系统需要的存储功能。目前该存储系统已应用到船载航行数据记录仪并运行良好。 |