1 引言 FLASH(闪速存储器)作为一种安全、快速的存储体,具有体积小、容量大、成本低、掉电数据不丢失等一系列优点,已成为嵌入式系统中数据和程序最主要的 载体。由于FLASH在结构和操作方式上与硬盘、E2ROM等其他存储介质有较大区别,使用FLASH时必须根据其自身特性,对存储系统进行特殊设计,以 保证系统的性能达到最优。 2 FLASH的特点 FLASH是一种非易失性存储器NVM(Non-Volatile Memory),根据结构的不同可以将其分成NOR FLASH和NAND FLASH两种。但不管哪一种都具有如下特点: 1. 区块结构 FLASH在物理结构上分成若干个区块,区块之间相互独立。比如NOR FLASH把整个Memory分成若干个Sector,而NAND FLASH把整个Memory分成若干个Block; 2. 先擦后写 由于FLASH的写操作只能将数据位从1写成0,不能从0写成1,所以在对存储器进行写入之前必须先执行擦操作,将预写入的数据位初始化为1。擦操作的最小单位是一个区块,而不是单个字节。 3. 操作指令 除了NOR FLASH的读,FLASH的其它操作不能像RAM那样,直接对目标地址进行总线操作。比如执行一次写操作,它必须输入一串特殊的指令(NOR FLASH),或者完成一段时序(NAND FLASH)才能将数据写入到FLASH中。 4. 位反转 由于FLASH固有的电器特性,在读写数据过程中,偶然会产生一位或几位数据错误。这就是位反转。位反转无法避免,只能通过其他手段对结果进行事后处理。 5. 坏块 FLASH在使用过程中,可能导致某些区块的损坏。区块一旦损坏,将无法进行修复。如果对已损坏的区块进行操作,可能会带来不可预测的错误。尤其是NAND FLASH在出厂时就可能存在这样的坏块(已经被标识出)。 3 关键设计 3.1 FLASH通用设计 对于一个嵌入式系统,设备的兼容性越好,系统可行性就越好,产品也就越有竞争力。所以,为了兼容不同类型的FLASH设备,对FLASH进行通用设计至关重要。 对于NOR FLASH,数据的读操作可以通过独立的数据总线和地址总线快速完成,然而NOR FLASH的其他操作需要通过特殊的指令来完成,更糟糕的是不同厂商生产的芯片这些指令互不相同。这就导致了设备的不兼容。 对于NAND FLASH,也存在这样的问题。NAND FLASH可以根据相同的指令读取芯片的厂商号和设备号,从而通过识别设备号调用对应的时序流程实现操作。但是,系统中太多的判断,会使得程序的结构变得 非常复杂。所以,在一定的条件下,NAND FLASH设备还是不兼容的。 为了解决这一问题,一个较好的方法是将FLASH的各个操作指令以及结构特性按照统一的格式存放到FLASH中固定位置。系统初始化时,将这个结构读入系 统,通过分析这个结构,可以获得关于芯片所有相关信息,包括操作指令,区块分布等等。这样,系统可以轻松实现对不同型号FLASH的所有操作,极大地提高 了设备的扩展性。 3.2 双模式文件系统设计 嵌入式系统中文件数据的存放一般有两种结构,一种是索引格式的线性结构,一种是非线性的链表式结构。这两种结构各有优缺点。比如对于系统配置、点阵字库等 一些具有固定结构的系统数据,索引结构比链表式结构更有效率。但对于经常更新的用户数据,链表式结构要比索引结构更灵活。如果系统能将两种结构集成,势必 能将性能发挥到最优。 实现这种集成的方法是将设备定义成若干个分区,每个分区相互独立,不同分区可以使用不同的文件模式。这样,不同类型的数据就可以根据自己的属性选择存放的分区。比如系统数据存放在使用索引线性结构的分区,用户数据存放在使用链式非线性结构的分区。 3.3 坏块处理 FLASH中的坏块处理是一件很棘手的问题,如果没有有效的管理,对系统的稳定性会造成严重影响。一个可行的解决方法是生成一张坏块表,坏块表中记录所有 坏块的块号,并且按块号从小到大排序,坏块表在读写过程中动态更新。当读写数据时,遍历坏块表中的块号,将文件的逻辑地址转换成对应FLASH 物理地址,以保证所用的FLASH地址空间不存在坏块。 4 系统实现 4.1 结构定义 图1 - 存储结构
|