学习结构如目录所示:
一、NAND FLASH概述
二、NAND FLASH的参数及物理结构
三、NAND FLASH的地址访问方法
四、 NAND FLASH的操作方法
五、 NAND FLASH的其他一些补充

一、Nand Flash的概述

1、Nand Flash的定义:

      NAND Flash 在嵌入式系统中的地位与PC机上的硬盘是类似的。用于保存系统运行所必需的操作系统,应用程序,用户数据,运行过程中产生的各类数据,系统掉电后数据不会丢失。

2、 Nand Flash的几个重要的基本特性:

      a)、NandFlash的IO接口

      对于Norflash、dram 之类的存储设备,CPU 可以直接通过地址总线对其进行访问,而 Nand Flash 没有这类的总线,只有 IO 接口,只能通过复用的 IO接口发送命令和地址,从而实现对 Nand Flash 内部数据进行访问。(端口的复用)

      b)、NandFlash的读、写、擦除操作:

      读写是以页为单位的,擦除是以块为单位的。
      对于Nand的写操作,只能由1变成0,而不能由0变成1。所以必须先对nand执行erase操作,即将0变成1,然后再写(使对应的1变成0)

      c)、存储在Nand中的数据容易发生错误,所以采取一定的算法对数据进行编码和解码很有必要。在数据存储到nand flash之前进行编码,连同校验数据一同存储到nand之中;在数据从nand读出之后进行解码,以验证数据是否出错。(BCH)

3、与Nand Flash相关的名词术语:

      a)、ONFI标准

      ONFI(Open NAND Flash Interface,开放式NAND闪存接口)规范是一种Flash闪存接口的标准,它是Intel为统一当初混乱的闪存接口所倡导的标准。因为在此之前,市场上销售的NAND闪存芯片在引脚定义上都不完全相同。这就使得为一家公司设计的控制器,很有可能无法用在另一家公司的产品上。比如为东芝芯片设计的控制器,就无法用在三星或海力士的产品上,这就给上游的主控设计商以及最终的产品设计人员带来了很大的困难。
     为此,Intel联合多家NAND Flash厂商制定了ONFI标准,统一NAND Flash芯片的引脚定义,并在此基础上采用新的技术以实现新的功能。

      b)、Block Management(坏)块管理

      NandFlash 由于其物理特性,只有有限的擦写次数,超过那个次数,基本上就是坏了。在使用过程中,有些 Nand Flash 的 block 会出现被用坏了,当发现了,要及时将此 block 标注为坏块,不再使用。于此相关的管理工作,属于 Nand Flash 的坏块管理的一部分工作。

      c)、Wear-Leveling 负载平衡

      NandFlash 的 block 的管理,还包括负载平衡。
      正是由于 Nand Flash 的 block,都是有一定寿命限制的,所以如果你每次都往同一个 block擦除然后写入数据,那么那个 block 就很容易被用坏了,所以我们要去管理一下,将这么多次的对同一个 block 的操作,平均分布到其他一些 block 上面,使得在 block 的使用上,相对较平均,这样相对来说,可以更能充分利用 Nand Flash。

      d)、ECC 错误校验码

      NandFlash 物理特性上使得其数据读写过程中会发生一定几率的错误,所以要有个对应的错误检测和纠正的机制,于是才有此 ECC,用于数据错误的检测与纠正。Nand Flash 的 ECC,常见的算法有海明码和BCH,这类算法的实现,可以是软件也可以是硬件。不同系统,根据自己的需求,采用对应的软件或者是硬件。

      e)、SLC 和MLC

      >> SLC(Single Level Cell)
      单个存储单元,只存储一位数据,表示 1 或 0。
      对于数据的表示,单个存储单元中内部所存储电荷的电压,和某个特定的阈值电压 Vth相比,如果大于此 Vth 值,就是表示 1,反之,小于 Vth,就表示 0.
      >> MLC(Multi Level Cell)
      与 SLC 相对应的,就是单个存储单元,可以存储多个位,比如 2 位,4位等。其实现机制,说起来比较简单,
      就是通过控制内部电荷的多少,分成多个阈值,通过控制里面的电荷多少,而达到我们所需要的存储成不同的数据。比如,假设输入电压是 Vin=4V(实际没有这样的电压,此处只是为了举例方便),那么,可以设计出 2 的 2 次方=4 个阈值, 1/4 的 Vin=1V,2/4 的 Vin=2V,3/4 的 Vin=3V,Vin=4V,分别表示 2 位数据 00,01,10,11,对于写入数据,就是充电,通过控制内部的电荷的多少,对应表示不同的数据。

4、Nand Flash的数据存储:

      NAND flash的数据是以bit的方式保存;对于SLC而言,一个cell只能存储一个bit,而对于MLC而言,一个cell可以存储2个bit;这些cell以8个或者16个为单位连成bit line,形成所谓的byte(x8)/word(x16),即我们所说的NAND device的位宽。
      NAND flash以页(后面会介绍到)为单位读写数据,而以块为单位擦出数据。

vin码校验Java代码_数据


 

 

二、Nand Flash的参数及结构

1、MT29F32G08CBACA型号分析

vin码校验Java代码_寄存器_02

2、MT29F32G08CBACA的封装及设备结构

vin码校验Java代码_数据_03

3、MT29F32G08CBACA存储单元组织结构

vin码校验Java代码_数据_04

Organization

– Page size : 4320bytes (4096 + 224 bytes)
– Block size: 256pages (1024K + 56K bytes)
– Plane size: 2 planesx 2048 blocks per plane
– Device size: 32Gb:4096 blocks

      NANDFLASH存储器MT29F32G08CBACA的总容量为34560Mb(4G+224M),其中包括两个plane,每个plane由2048个block (块) ,每个block又由256 pages组成,而每个page包含了大小为4K字节的Data area(数据存储区域) 和224字节的Spare area(备用区域)
      OOB:每页还有一块区域,在Linux 系统中,称为OOB(Out Of Band),这个区域最初基于Nand Flash在读写数据时容易错误的特性,为了保证数据的正确性,采用相应的检测和纠错机制(EDC/ECC),而设计的用于放置数据的校验值的区域。

      关于 oob具体用途,总结起来有:
      a)、标记是否是坏块
      b)、存储ECC数据
      c)、存储一些和文件系统相关的数据。如jffs2就会用到这些空间存储一些特定信息,而yaffs2文件系统,会在oob中,存放很多和自己文件系统相关的信息。

4、MT29F32G08CBACA功能框图

vin码校验Java代码_数据_05

由于,I/O线是数据地址和命令复用的,所以要根据ALE和CLE的高低电平可以判断I/O线上传递过来的是地址,命令还是数据。

5、nand flash的数据流向

vin码校验Java代码_数据_06

读时:
      发送第一条命令00h时,实际的物理存储单元的数据先放到页缓冲(pageregister)里
      发送第二条命令30h后,Nand flash控制器开始从页缓存中读取数据,读到其中fifo中,再读fifo数据到内存。

写时:
      Nand flash控制器将memory中要写入nand的数据先读到其中的fifo中,发送第1条命令80h时,nand flash控制器将数据弄到nond flash的一个页缓存(pageregister)里
      发送第二条命令10h后,实际的编程动作才开始,才开始把页缓存中的数据,一点点写到物理单元中去。

6、nand flash的引脚定义

vin码校验Java代码_寄存器_07

7、nand flash的硬件连接

vin码校验Java代码_复用_08

 

三、Nand Flash的地址访问方法 

      MT29F32G08CBACA的访问地址序列

      MT29F32G08CBACA总共的容量为34560MB(4G+224MB),8位位宽,需要36位的访问地址。但芯片只提供了8根地址线(复用),明显不足。所以对MT29F32G08CBACA访问时,访问地址被分割成5个地址序列,这5个地址序列中的前两个为页内地址,后三个为页面地址。两个页内地址序列有效地址位为13位,以满足对页内4096+224字节空间的访问;后三个地址序列有效地址为21位,以满足对一个芯片内共2*2048(块)*256(页)个页面的访问。MT29F32G08CBACA地址序列表见下图:

vin码校验Java代码_复用_09


      在实际驱动程序编程时用户必须严格按照这五个地址序列来向NFADDR寄存器中分别写入每个序列地址。也就是说用户发出一个完整的访问地址必须写5次NFADDR寄存器。

      值得注意的是:小页面NAND flash仅仅提供了一个地址序列,8个访问地址位来访问512+16字节的页内空间,访问地址位明显足。所以小页面NANDflash将页内地址分割成A、B、C三个区,分别用不同的读命令进行访问,以弥补页内访问地址序列地址位不足的缺陷。

      相对而言,大页面NAND flash它为页内地址访问提供了足够的地址序列和访问地址位(13位地址访问4096+224字节空间,足够了),所以大页面NAND flash对页内地址的访问也更为简洁。

vin码校验Java代码_复用_10

 

四、nand flash的操作方法 

1、命令字

      NAND Flash的读取和烧录以(page)页为基础,擦除以块为单位。那么,在NANDFlash上有三种基本的操作:读取一个页, 烧录一个页和擦除一个块,这三个基本操作有各自的命令序列。
      实际上,大多数NAND Flash除提供了这三个基本操作外,还提供了很多其他的操作及操作命令序列,如:MT29F32G08CBACA就提供了Multi PlaneProgram(多层烧写)、Multi Plane Erase(多层擦除)、Copy-back Program(同层页复制)、Multi-PlaneCopy-Back Program(多层同层页复制)、Multi PlaneErase(多层擦除)、EDC Operation(ECD操作)、reset(复位)等操作。
      这里涉及到了一个层的概念,什么是层?有什么特性?他的作用是啥?
      层就是将芯片各块平均分配到块组,如:块编号为奇数为一组,块编号为偶数的分为一组,这样的块组就叫层。
      层有这样的特性:用户可对不同层中的块同时进行擦除和烧写甚至复制。MT29F32G08CBACA中的块分成了2个层,有些NAND flash分成了4个层。
      作用:分层操作能成倍提高烧写、擦除速度。

2、读页操作的分析

      读页操作有两个命令序列,命令字分别为00h、30h。

vin码校验Java代码_vin码校验Java代码_11


      a)、读页流程

      读页操作有两个命令序列,命令字分别为00h、30h。
      整个流程比较简单:
            先写读页操作的第一个命令序列的命令字00h,然后写页地址;
            然后写第二个命令序列的命令字30h。
            再读取状态寄存器的位0,为1后就可以从NFDATA连续读出页内数据。 

 2、读页时序分析

vin码校验Java代码_数据_12


      a)、黄色竖线穿过的第一行,是CLE。将CLE置1,就说明你将要通过I/O复用端口发送进入Nand Flash的,是命令,而不是地址或者其他类型的数据。只有这样将CLE置1,

      使其有效,才能去通知了内部硬件逻辑,你接下来将收到的是命令,内部硬件逻辑,才会将受到的命令,放到命令寄存器中,才能实现后面正确的操作,否则,不去将CLE置1

      使其有效,硬件会无所适从,不知道你传入的到底是数据还是命令了。

      b)、而第二行,是CE#,那一刻的值是0,就是片选有效。

      c)、第三行是WE#,意思是写使能。因为接下来是往nand Flash里面写命令,所以,要使得WE#有效。

      d)、第四行,是ALE是低电平,而ALE是高电平有效,此时意思就是使其无效。而对应地,前面介绍的,使CLE有效,因为将要数据的是命令,而不是地址。接下来的要输入地址的时候,就要使其有效,而使CLE无效了。

      e)、第五行,RE#,此时是高电平,无效。可以看到,知道后面低6阶段,才变成低电平,才有效,因为那时候,要发生读取命令,去读取数据。

      f)、第六行,就是我们重点要介绍的,复用的输入输出I/O端口了,此刻,还没有输入数据,接下来,在不同的阶段,会输入或输出不同的数据/地址。

      g)、第七行,R/B#,高电平,表示R(Ready)/就绪,因为到了后面的第5阶段,硬件内部,在第四阶段,接受了外界的读取命令后,把该页的数据一点点送到页寄存器中,这段时间,属于系统在忙着干活,属于忙的阶段,所以,R/B#才变成低,表示Busy忙的状态的。

      读操作过程的解释

      1) 操作准备阶段:此处是读(Read)操作,所以,先发读命令的第一个阶段的0x00,表示,让硬件先准备一下,接下来的操作是读。

      2) 发送两个周期的列地址,即页内地址。表示要从一个页的什么位置开始读取数据。

      3) 接下来再传入三个行地址,即页号。

      4) 再发一个读操作第二个周期的命令0x30。接下来,就是硬件内部自己的事情了。

      5) Nand Flash内部硬件逻辑,负责去按照你的要求,根据传入的地址,找到哪个块中的哪个页,然后把整个这一页的数据,都一点点搬运到页缓存中去。而在此期间,你所能做的事,也就只需要去读取状态寄存器,看看对应的位的值,也就是R/B#那一位,是1还是0,0的话,就表示,系统是busy,仍在”忙“(着读取数据),如果是1,就说系统活干完了,忙清了,已经把整个页的数据都搬运到页缓存里去了,你可以接下来读取你要的数据了。对于这里。估计有人会问了,这一个页一共4096+224字节,如果我传入的页内地址,就像上面给的1028一类的值,只是想读取1028到2011这部分数据,而不是页开始的0地址整个页的数据,那么内部硬件却读取整个页的数据出来,岂不是很浪费吗?答案是,的确很浪费,效率看起来不高,但是实际就是这么做的,而且本身读取整个页的数据,相对时间并不长,而且读出来之后,内部数据指针会定位到你刚才所制定的1208的那个位置。

      6) 接下来,就是你“窃取”系统忙了半天之后的劳动成果的时候了。通过先去Nand Flash的控制器中的数据寄存器中写入你要读取多少个字节(byte)/字(word),然后就可以去Nand Flash的控制器的FIFO中,一点点读取你要的数据了。

      至此,整个Nand Flash的读操作就完成了。

3、读ID

      读设备ID只有一个命令字90h,先向命令寄存器写入90h再向地址寄存器写入00h可启动读ID操作,后续连续5次读取数据寄存器操作可以读出5个包含了全部id内容的数据。这5个数据内容如下:

vin码校验Java代码_vin码校验Java代码_13

      下面对几个重要的id内容做一个简单的介绍:

vin码校验Java代码_寄存器_14

vin码校验Java代码_数据_15

vin码校验Java代码_vin码校验Java代码_16

 

五、nand flash的其他一些补充

1、NAND FLASH控制器

vin码校验Java代码_寄存器_17

      地址空间:只写空间,用来写入控制器将要写到nand flash中的地址
      命令空间:只写空间,用来写入控制器将要发送给nand flash的命令
      数据空间:读写,用来写入将要发送给nand flash的数据,或是存放从nand flash中读取到的数据

      注:这就体现出了控制器的作用了。

      A、若没有控制器,对于写命令 “80h”这一操作,你就须要做很多事情:Set pin CLE high, set pin WE# low,等等,可能你还要以配置GPIO的形式让相应的数据在线出现 “80h”。
      B、有了控制器,你只需 REG32(0xBA400000) = 80h, 剩下的事情就让控制器去做

2、BCH控制器

      我们将以读写的例子进行说明:

      Nand_read_page
      在读操作中, NAND Flash控制器首先执行页读取(Page read)操作,从目标 Nand Flash读出一整页数据,然后交由给BCH译码模块执行译码(BCH_decoding),译码完毕后,可能通过软件(驱动程序)判断有没有数据坏块,如果有的话,在软件中要执行一个 “correct()”函数来纠正其中的错误。之后 ,由CPU或者DMA将译码后的数据写入Memory的一个buffer中。

      Nand_program_page
      在写操作中,CPU或者DMA先是把一个buffer的数据交给BCH编译模块去执行编码(BCH_encoding), 编码完毕后,再由CPU或者DMA将编码后相关的数据(包括data区和oob区)写入到Nand Flash中。

到这里我们已经对nand flash有了一个大体的认识,下面我们开始看mtd 下的nand flash 驱动程序了,以及我调试时遇到的问题!!!!!!!!!!!!!!!