1. 首先对于nandflash 编程有三个方面
1. nandflash 存储器,当然这是重点,因为对于nandflash 编程就是对nandflash 进行读写擦除等操作。
2. nandflash 控制器,这里S3C2440 已经集成了,对我们可见的就是一堆的寄存器。对于2440 编程很多时候是设置一堆的寄存器再加上对设备的时序操作。
3. nandflash 的引脚配置,因为2440 的IO 一般为多功能复用IO 口。
2. 然后第二个方面是nandflash 的结构和操作
1. 对应一款具体的nandflash 芯片手册上会给出芯片的结构,nandflash 分为俩部分一是main erea 和 spare erea 。main 区保存数据,spare 区存储附加信息,坏块 ECC 校验等等。 NAND FLASH 的结构为一片Nand flash 为一个设备(device) ,1 (Device) = xxxx (Blocks) ,1 (Block) = xxxx (Pages) ,1(Page) =528 (Bytes) = 数据块大小(512Bytes) + OOB 块大小(16Bytes ,数据块为main 区,OOB 为spare 区,除OOB 第六字节外,通常至少把OOB 的前3 个字节存放Nand Flash 硬件ECC 码) 。关于 OOB 区,是每个 Page 都有的。 Page 大小是 512 字节的 NAND 每页分配 16 字节的 OOB ;如果 NAND 物理上是 2K 的 Page ,则每个 Page 分配 64 字节的 OOB 。具体分配详见数据手册。
2. 坏块, 对于 nandflash 要是没有坏块那就比较完美了但是 nandflash 的工艺决定了 nand 的坏块不可避免(具体是什么原因应该和他的存储方式有 关),正是由于坏块的存在所以使得使用 nand 存储变得复杂。首先对于坏块的定义,是指一块中存在一位或者多位不确定的状态。
3. 坏块的分类,坏块分为俩种,一是出厂是就已经存在的坏块,固有坏块。对于固有坏块,芯片厂已经将坏块标记,对于不同的芯片标记的地方不同,以 sangsun 公司为例, 小的就是 1page 512byte ,坏块检查 SPARE DATA 的第六个字节。
大的就是 1page 2048byte ,坏块检查 SPARE DATA 的第 1 个字节。一般标记在每一个块的第一页和第二页的第六个字节或第一个字节为非0xff 一般写为0 。二是使用中出现的坏块,这一部分的坏块需要自己建立坏块表进行标记管理。
4. 坏块的管理,首先对于坏块的管理注意, nandflash 是对页进行读写,对块进行擦除,擦除有可能把坏块标记擦除,所以操作前先要判断是否为坏块。对于 坏块的管理网上有一个有个很好的想法,我觉得很好,对于整个 nandflash 进行分三个区域, 第一个区使用信息(包括坏块表,使用Block 数目等,预留10 个Block ),第二个区为数据记录区,第三个区为坏块映射区(专用于替换坏块,为保留区,不能直接往里面写数据,为128 个Block )。
从 前10 个Block 中选择一个好的Block 来记录整个nand 的坏块信息和其他信息,然后第二个区为真正的数据记录区,最后第三个区为坏块的替换区域。 开始前运行一个坏块扫描程序来建立整个坏块表,以后再产生的坏块同样记录在坏块表中。再写数据时先查询坏块表是否为坏块,如果是坏块,则就数据写入到替换 区域的块中。
5. ECC 以三星公司的 K9F2G08U0A nandflash 为例讲我的理解,首先对于ECC 是一种错误检测和纠正的校验方法,原理比较复杂,三星公司有文档说明,可以用软件和硬件实 现,S3C2440 硬件产生ECC ,简化了编程。ECC 分为俩部分一是对于主数据main 区的ECC ,二是对spare 区的ECC 。对于ECC 校验的过程 如下,首先读写一页数据后,硬件自动生成ECC 数据到 NFMECCD0/1 ( main 区数据 ECC ),读写 spare 区后自动生成 ECC 到 NFSECCD0/1 ( spare 区数据 ECC )。然后我们需要把这俩个 ECC 数据保存到 nand 的 spare 区,对于 K9F2G08U0A spare 区有64byte ,不要使用第1 、2byte ,因为出厂时的坏块标记保存在每个Block 的第一二页的第一二个字节,为了统一,以后自己遇到坏块时也统一 使用一二个字节标记坏块。使用其他的字节,(自己选择)来保存Main 区的ECC 和spare 区的ECC 。当读出main 区的数据时,同样硬件自动生成 ECC 到 NFMECCD0/1 寄存器,再把上次保存的 ECC 数据出来俩次进行比较相同则没有错误,而我们只需要将取出的 ECC 数据放入寄存器 NFMECCD 中,硬件自动进行比较,我只有读 ECC 状态寄存器 NFESTAT0/1 就可以得到结果。同样对 spare 进行检验,同时对错误进行处理。
补充:昨天写的博文,今天又看了一些书,补充一下。
首先我的芯片是sangsun公司的 K9F2G08U0B 恩,芯片的大小是256M 8位IO 手册上没有明确写整个芯片分为多少个plane 但我看了一下后面的一下描述我认为整个芯片分为2个plane。
另 外还有一个比较重要的是,改正一下,nandflash的存储区包括俩部分,mian区和spare区,另外nandflash还有寄存器--状态寄存 器。在完成读写操作后,通过 读状态寄存器命令 这个操作读出nandflash中的状态判断读写操作是否成功。注意这个寄存器在nandflash中,不是nandflash控制器中的寄存器。寄存器 值的意义在手册后面有说明。