如何编写linux下nand flash驱动-1

本文详细介绍了 NAND Flash 的硬件特性和工作原理,包括 SLC 和 MLC 的区别,坏块管理,以及特殊的硬件特性如交错页编程等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介】如何编写linuxnand flash 驱动-1

version: 1.0

date:20090721

Author crifan

Mail:green-waste(At)163.com

【编写驱动之前要了解的知识】

1.       硬件特性:

Flash 的硬件实现机制】

Flash 全名叫做 Flash Memory ,属于非易失性存储设备 (Non-volatile Memory Device) ,与此相对应的是易失性存储设备 (Volatile Memory Device) 。关于什么是非易失性 / 易失性,从名字中就可以看出,非易失性就是不容易丢失,数据存储在这类设备中,即使断电了,也不会丢失,这类设备,除了 Flash ,还有其他比较常见的入硬盘, ROM 等,与此相对的,易失性就是断电了,数据就丢失了,比如大家常用的内存,不论是以前的 SDRAM DDR SDRAM ,还是现在的 DDR2 DDR3 等,都是断电后,数据就没了。

 

Flash 的内部存储是 MOSFET ,里面有个悬浮门 (Floating Gate) ,是真正存储数据的单元。

Flash 之前,紫外线可擦除 (uv-erasable) EPROM ,就已经采用用 Floating Gate 存储数据这一技术了。

【简介】如何编写linux下nand flash驱动-1 - green-waste - 活着,生存,状态,不虚度。。。

1 . 典型的 Flash 内存单元的物理结构

数据在 Flash 内存单元中是以电荷 (electrical charge) 形式存储的。存储电荷的多少,取决于图中的外部门( external gate )所被施加的电压,其控制了是向存储单元中冲入电荷还是使其释放电荷。而数据的表示,以所存储的电荷的电压是否超过一个特定的阈值 Vth 来表示。

 

SLC MLC 的实现机制】

Nand Flash 按照内部存储数据单元的电压的不同层次,也就是单个内存单元中,是存储 1 位数据,还是多位数据,可以分为 SLC MLC

1.       SLC Single Level Cell:

单个存储单元,只存储一位数据,表示成 1 0.

就是上面介绍的,对于数据的表示,单个存储单元中内部所存储电荷的电压,和某个特定的阈值电压 Vth ,相比,如果大于此 Vth 值,就是表示 1 ,反之,小于 Vth ,就表示 0.

对于 nand Flash 的数据的写入 1 ,就是控制 External Gate 去充电,使得存储的电荷够多,超过阈值 Vth ,就表示 1 了。而对于写入 0 ,就是将其放电,电荷减少到小于 Vth ,就表示 0 了。

关于为何 Nand Flash 不能从 0 变成 1 ,我的理解是,物理上来说,是可以实现每一位的,从 0 变成 1 的,但是实际上,对于实际的物理实现,出于效率的考虑,如果对于,每一个存储单元都能单独控制,即, 0 变成 1 就是,对每一个存储单元单独去充电,所需要的硬件实现就很复杂和昂贵,同时,所进行对块擦除的操作,也就无法实现之前的,一闪而过的速度了,也就失去了 Flash 的众多特性了。

 

2.       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 ,对于写入数据,就是充电,通过控制内部的电荷的多少,对应表示不同的数据。

对于读取,则是通过对应的内部的电流(与 Vth 成反比),然后通过一系列解码电路完成读取,解析出所存储的数据。这些具体的物理实现,都是有足够精确的设备和技术,才能实现精确的数据写入和读出的。

单个存储单元可以存储 2 位数据的,称作 2 2 次方= 4 Level Cell ,而不是 2 Level Cell ,这点,之前差点搞晕了。。。,同理,对于新出的单个存储单元可以存储 4 位数据的,称作 2 4 次方= 16 Level Cell

 

【关于如何识别 SLC 还是 MLC

Nand Flash 设计中,有个命令叫做 Read ID ,读取 ID ,意思是读取芯片的 ID ,就像大家的身份证一样,这里读取的 ID 中,是读取好几个字节,一般最少是 4 个,新的芯片,支持 5 个甚至更多,从这些字节中,可以解析出很多相关的信息,比如此 Nand Flash 内部是几个芯片( chip )所组成的,每个 chip 包含了几片( Plane ),每一片中的页大小,块大小,等等。在这些信息中,其中有一个,就是识别此 flash SLC 还是 MLC 。下面这个就是最常见的 Nand Flash datasheet 中所规定的,第 3 个字节, 3rd byte ,所表示的信息,其中就有 SLC/MLC 的识别信息:


 



 

Description

I/O7

I/O6

I/O5 I/O4

I/O3 I/O2

I/O1 I/O0

Internal

Chip Number

1

2

4

8

 

 

 

 

0     0

0     1

1     0

1     1

Cell Type

2 Level Cell

4 Level Cell

8 Level Cell

16 Level Cell

 

 

 

0      0

0      1

1      0

1      1

 

Number of

Simultaneously

Programmed Pages

1

2

4

8

 

 

0      0

0      1

1      0

1      1

 

 

Interleave Program

Between multiple chips

Not Support

Support

 

0

1

 

 

 

Cache Program

Not Support

Support

0

1

 

 

 

 

1.Nand Flash 3 ID 的含义

 

Nand Flash 的物理存储单元的阵列组织结构】

Nand flash 的内部组织结构,此处还是用图来解释,比较容易理解:

【简介】如何编写linux下nand flash驱动-1 - green-waste - 活着,生存,状态,不虚度。。。

2.Nand Flash 物理存储单元的阵列组织结构

上图是 K9K8G08U0A datasheet 中的描述。

简单解释就是 :

1. 一个 nand flash 由很多个块( Block )组成,块的大小一般是 128KB 256KB 512KB ,此处是 128KB

2. 每个块里面又包含了很多页( page )。每个页的大小,对于现在常见的 nand flash 多数是 2KB ,更新的 nand flash 4KB ,这类的,页大小大于 2KB nand flash ,被称作 big block ,对应的发读写命令地址,一共 5 个周期 (cycle) ,而老的 nand flash ,页大小是 256B 512B ,这类的 nand flash 被称作 small block ,。地址周期只有 4 个。

而块,也是 Nand Flash 的擦除操作的基本 / 最小单位。

3. 每一个页,对应还有一块区域,叫做空闲区域( spare area / 冗余区域( redundant area ),而 Linux 系统中,一般叫做 OOB Out Of Band ),这个区域,是最初基于 Nand Flash 的硬件特性:数据在读写时候相对容易错误,所以为了保证数据的正确性,必须要有对应的检测和纠错机制,此机制被叫做 EDC(Error Detection Code)/ECC Error Code Correction, 或者 Error Checking and Correcting ),所以设计了多余的区域,用于放置数据的校验值。

页是 Nand Flash 的写入操作的基本 / 最小的单位。

 

Nand Flash 数据存储单元的整体架构】

简单说就是,常见的 nand flash ,内部只有一个 chip ,每个 chip 只有一个 plane

而有些复杂的,容量更大的 nand flash ,内部有多个 chip ,每个 chip 有多个 plane 。这类的 nand flash ,往往也有更加高级的功能,比如下面要介绍的 Multi Plane Program Interleave Page Program 等。

比如,型号为 K9K8G08U0A 这个芯片( chip ),内部有两个 K9F4G08U0A ,每个 K9F4G08U0A 包含了 2 Plane ,每个 Plane 1Gb ,所以 K9F4G08U0A 的大小是 1Gb × 2 2Gb 256MB ,因此, K9K8G08U0A 内部有 2 K9F4G08U0A ,即 4 Plane ,总大小是 4 × 256MB 1GB

而型号是 K9WAG08U1A nand flash ,内部包含了 2 K9K8G08U0A ,所以,总容量是 K9K8G08U0A 的两倍= 1GB × 2 2GB ,类似地 K9NBG08U5A ,内部包含了 4 K9K8G08U0A ,总大小就是 4 × 1GB 4GB

 

Flash 名称的由来】

Flash 的擦除操作是以 block 块为单位的,与此相对应的是其他很多存储设备,是以 bit 位为最小读取 / 写入的单位, Flash 是一次性地擦除整个块:在发送一个擦除命令后,一次性地将一个 block ,常见的块的大小是 128KB/256KB 。。,全部擦除为 1 ,也就是里面的内容全部都是 0xFF 了,由于是一下子就擦除了,相对来说,擦除用的时间很短,可以用一闪而过来形容,所以,叫做 Flash Memory 。中文有的翻译为 (快速)闪存。

 

Flash 相对于普通设备的特殊性】

1.       上面提到过的, Flash 最小操作单位,有些特殊。

一般设备,比如硬盘 / 内存,读取和写入都是以 bit 位为单位,读取一个 bit 的值,将某个值写入对应的地址的位,都是可以按位操作的。

但是 Flash 由于物理特性,使得内部存储的数据,只能从 1 变成 0 ,这点,可以从前面的内部实现机制了解到,只是方便统一充电,不方便单独的存储单元去放电,所以才说,只能从 1 变成 0 ,也就是释放电荷。

所以,总结一下 Flash 的特殊性如下:

 

 

普通设备 ( 硬盘 / 内存等 )

Flash

读取 / 写入的叫法

读取 / 写入

读取 / 编程 (Program)

读取 / 写入的最小单位

Bit/

Page/

擦除 (Erase) 操作的最小单位

Bit/

Block/

擦除操作的含义

将数据删除 / 全部写入 0

将整个块都擦除成全是 1 ,也就是里面的数据都是 0xFF

对于写操作

直接写即可

在写数据之前,要先擦除,然后再写

2.Flash 和普通设备相比所具有的特殊性

注:

之所以将写操作叫做编程,是因为, flash 和之前的 EPROM EEPROM 继承发展而来,而之前的 EEPROM(Electrically Erasable Programmable Read-Only Memory) ,往里面写入数据,就叫做编程 Program ,之所以这么称呼,是因为其对数据的写入,是需要用电去擦除 / 写入的,就叫做编程。

对于目前常见的页大小是 2K/4K Nand Flash ,其块的大小有 128KB/256KB/512KB 等。而对于 Nor Flash ,常见的块大小有 64K/32K 等。

③在写数据之前,要先擦除,内部就都变成 0xFF 了,然后才能写入数据,也就是将对应位由 1 变成 0

 

Nand Flash 引脚 (Pin) 的说明】

【简介】如何编写linux下nand flash驱动-1 - green-waste - 活着,生存,状态,不虚度。。。

3.Nand Flash 引脚功能说明

上图是常见的 Nand Flash 所拥有的引脚( Pin )所对应的功能,简单翻译如下:

1.       I/O0 ~ I/O7 :用于输入地址 / 数据 / 命令,输出数据

2.       CLE Command Latch Enable ,命令锁存使能,在输入命令之前,要先在模式寄存器中,设置 CLE 使能

3.       ALE Address Latch Enable ,地址锁存使能,在输入地址之前,要先在模式寄存器中,设置 ALE 使能

4.       CE# Chip Enable ,芯片使能,在操作 Nand Flash 之前,要先选中此芯片,才能操作

5.       RE# Read Enable ,读使能,在读取数据之前,要先使 CE #有效。

6.       WE# Write Enable ,写使能 , 在写取数据之前,要先使 WE #有效。

7.       WP# Write Protect ,写保护

8.       R/B#:Ready/Busy Output, 就绪 / , 主要用于在发送完编程 / 擦除命令后 , 检测这些操作是否完成 , , 表示编程 / 擦除操作仍在进行中 , 就绪表示操作完成 .

9.       Vcc Power ,电源

10.   Vss Ground ,接地

11.   N.C Non-Connection, 未定义,未连接。

[ 小常识 ]

在数据手册中,你常会看到,对于一个引脚定义,有些字母上面带一横杠的,那是说明此引脚 / 信号是低电平有效,比如你上面看到的 RE 头上有个横线,就是说明,此 RE 是低电平有效,此外,为了书写方便,在字母后面加“#”,也是表示低电平有效,比如我上面写的 CE #;如果字母头上啥都没有,就是默认的高电平有效,比如上面的 CLE ,就是高电平有效。

 

【为何需要 ALE CLE

突然想明白了, Nand Flash , 为何设计这么多的命令 , 把整个系统搞这么复杂的原因了 :

比如命令锁存使能 (Command Latch Enable,CLE) 地址锁存使能 (Address Latch Enable ALE) ,那是因为, Nand Flash 8 I/O ,而且是复用的,也就是,可以传数据,也可以传地址,也可以传命令,为了区分你当前传入的到底是啥,所以,先要用发一个 CLE (或 ALE )命令,告诉 nand Flash 的控制器一声,我下面要传的是命令(或地址),这样,里面才能根据传入的内容,进行对应的动作。否则 ,nand flash 内部 , 怎么知道你传入的是数据 , 还是地址 , 还是命令啊 , 也就无法实现正确的操作了 .

 

Nand Flash 只有 8 I/O 引脚的好处】

1.       减少外围引脚:相对于并口 (Parellel) Nor Flash 48 52 个引脚来说,的确是大大减小了引脚数目,这样封装后的芯片体积,就小很多。现在芯片在向体积更小,功能更强,功耗更低发展,减小芯片体积,就是很大的优势。同时,减少芯片接口,也意味着使用此芯片的相关的外围电路会更简化,避免了繁琐的硬件连线。

2.       提高系统的可扩展性,因为没有像其他设备一样用物理大小对应的完全数目的 addr 引脚,在芯片内部换了芯片的大小等的改动,对于用全部的地址 addr 的引脚,那么就会引起这些引脚数目的增加,比如容量扩大一倍,地址空间 / 寻址空间扩大一倍,所以,地址线数目 /addr 引脚数目,就要多加一个,而对于统一用 8 I/O 的引脚的 Nand Flash ,由于对外提供的都是统一的 8 个引脚,内部的芯片大小的变化或者其他的变化,对于外部使用者 ( 比如编写 nand flash 驱动的人 ) 来说,不需要关心,只是保证新的芯片,还是遵循同样的接口,同样的时序,同样的命令,就可以了。这样就提高了系统的扩展性。

 

Nand flash 的一些典型 (typical) 特性】

1. 页擦除时间是 200us ,有些慢的有 800us

2. 块擦除时间是 1.5ms.

3. 页数据读取到数据寄存器的时间一般是 20us

4. 串行访问( Serial access )读取一个数据的时间是 25ns ,而一些旧的 nand flash 30ns ,甚至是 50ns

5. 输入输出端口是地址和数据以及命令一起 multiplex 复用的。

以前老的 Nand Flash ,编程 / 擦除时间比较短,比如 K9G8G08U0M ,才 5K 次,而后来很多 6.nand flash 的编程 / 擦除的寿命,最多允许的次数,以前的 nand flash 多数是 10K 次,也就是 1 万次,而现在很多新的 nand flash ,技术提高了,比如, Micron MT29F1GxxABB Numonyx NAND04G-B2D/NAND08G-BxC ,都可以达到 100K ,也就是 10 万次的编程 / 擦除。和之前常见的 Nor Flash 达到同样的使用寿命了。

7.48 引脚的 TSOP1 封装   52 引脚的 ULGA 封装

 

Nand Flash 中的特殊硬件结构】

由于 nand flash 相对其他常见设备来说,比较特殊,所以,特殊的设备,也有特殊的设计,所以,有些特殊的硬件特性,就有比较解释一下:

1.       页寄存器( Page Register ):由于 Nand Flash 读取和编程操作来说,一般最小单位是页,所以, nand flash 在硬件设计时候,就考虑到这一特性,对于每一片,都有一个对应的区域,专门用于存放,将要写入到物理存储单元中去的或者刚从存储单元中读取出来的,一页的数据,这个数据缓存区,本质上就是一个 buffer ,但是只是名字叫法不同, datasheet 里面叫做 Page Register ,此处翻译为 页寄存器,实际理解为页缓存,更为恰当些。而正是因为有些人不了解此内部结构,才容易产生之前遇到的某人的误解,以为内存里面的数据,通过 Nand Flash FIFO ,写入到 Nand Flash 里面去,就以为立刻实现了实际数据写入到物理存储单元中了。而实际上,只是写到了这个页缓存中,只有等你发了对应的编程第二阶段的确认命令 0x10 之后,实际的编程动作才开始,才开始把页缓存中的数据,一点点写到物理存储单元中去。

所以,简单总结一下就是,对于数据的流向,实际是经过了如下步骤:

 

【简介】如何编写linux下nand flash驱动-1 - green-waste - 活着,生存,状态,不虚度。。。

4 Nand Flash 读写时的数据流向

 

Nand Flash 中的坏块 (Bad Block)

Nand Flash 中,一个块中含有 1 个或多个位是坏的,就成为其为坏块。

坏块的稳定性是无法保证的,也就是说,不能保证你写入的数据是对的,或者写入对了,读出来也不一定对的。而正常的块,肯定是写入读出都是正常的。

坏块有两种:

1 )一种是出厂的时候,也就是,你买到的新的,还没用过的 Nand Flash ,就可以包含了坏块。此类出厂时就有的坏块,被称作 factory (masked)bad block initial bad/invalid block ,在出厂之前,就会做对应的标记,标为坏块。

具体标记的地方是,对于现在常见的页大小为 2K Nand Flash ,是块中第一个页的 oob 起始位置(关于什么是页和 oob ,下面会有详细解释)的第 1 个字节(旧的小页面, pagesize 512B 甚至 256B nand flash ,坏块标记是第 6 个字节),如果不是 0xFF ,就说明是坏块。相对应的是,所有正常的块,好的块,里面所有数据都是 0xFF 的。

2 )第二类叫做在使用过程中产生的,由于使用过程时间长了,在擦块除的时候,出错了,说明此块坏了,也要在程序运行过程中,发现,并且标记成坏块的。具体标记的位置,和上面一样。这类块叫做 worn-out bad block

 

对于坏块的管理,在 Linux 系统中,叫做坏块管理( BBM Bad Block Managment ),对应的会有一个表去记录好块,坏块的信息,以及坏块是出厂就有的,还是后来使用产生的,这个表叫做坏块表( BBT Bad Block Table )。在 Linux 内核 MTD 架构下的 Nand Flash 驱动,和 Uboot Nand Flash 驱动中,在加载完驱动之后,如果你没有加入参数主动要求跳过坏块扫描的话,那么都会去主动扫描坏块,建立必要的 BBT 的,以备后面坏块管理所使用。

 

而关于好块和坏块, Nand Flash 在出厂的时候,会做出保证:

1. 关于好的,可以使用的块的数目达到一定的数目,比如三星的 K9G8G08U0M ,整个 flash 一共有 4096 个块,出厂的时候,保证好的块至少大于 3996 个,也就是意思是,你新买到这个型号的 nand flash ,最坏的可能, 3096 3996 100 个坏块。不过,事实上,现在出厂时的坏块,比较少,绝大多数,都是使用时间长了,在使用过程中出现的。

2. 保证第一个块是好的,并且一般相对来说比较耐用。做此保证的主要原因是,很多 Nand Flash 坏块管理方法中,就是将第一个块,用来存储上面提到的 BBT ,否则,都是出错几率一样的块,那么也就不太好管理了,连放 BBT 的地方,都不好找了, ^_^

 

一般来说,不同型号的 Nand Flash 的数据手册中,也会提到,自己的这个 nand flash ,最多允许多少个坏块。就比如上面提到的,三星的 K9G8G08U0M ,最多有 100 个坏块。

 

对于坏块的标记,本质上,也只是对应的 flash 上的某些字节的数据是非 0xFF 而已,所以,只要是数据,就是可以读取和写入的。也就意味着,可以写入其他值,也就把这个坏块标记信息破坏了。对于出厂时的坏块,一般是不建议将标记好的信息擦除掉的。

uboot 中有个命令是“ nand scrub ”就可以将块中所有的内容都擦除了,包括坏块标记,不论是出厂时的,还是后来使用过程中出现而新标记的。一般来说,不建议用这个。不过,我倒是经常用,其实也没啥大碍,呵呵。

最好用“ nand erase ”只擦除好的块,对于已经标记坏块的块,不擦除。

 

 

nand Flash 中页的访问顺序】

在一个块内,对每一个页进行编程的话,必须是顺序的,而不能是随机的。比如,一个块中有 128 个页,那么你只能先对 page0 编程,再对 page1 编程,。。。。,而不能随机的,比如先对 page3 ,再 page1 page2. page0 page4 . 。。。

 

【片选无关 ( CE don’t-care) 技术

很多 Nand flash 支持一个叫做 CE don’t-care 的技术,字面意思就是,不关心是否片选,

那有人会问了,如果不片选,那还能对其操作吗?答案就是,这个技术,主要用在当时是不需要选中芯片却还可以继续操作的这些情况:在某些应用,比如录音,音频播放等应用,中,外部使用的微秒( us )级的时钟周期,此处假设是比较少的 2us ,在进行读取一页或者对页编程时,是对 Nand Flash 操作,这样的串行( Serial Access )访问的周期都是 20/30/50ns ,都是纳秒( ns )级的,此处假设是 50ns ,当你已经发了对应的读或写的命令之后,接下来只是需要 Nand Flash 内部去自己操作,将数据读取除了或写入进去到内部的数据寄存器中而已,此处,如果可以把片选取消, CE# 是低电平有效,取消片选就是拉高电平,这样会在下一个外部命令发送过来之前,即微秒量级的时间里面,即 2us 50ns 2us ,这段时间的取消片选,可以降低很少的系统功耗,但是多次的操作,就可以在很大程度上降低整体的功耗了。

总结起来简单解释就是:由于某些外部应用的频率比较低,而 Nand Flash 内部操作速度比较快,所以具体读写操作的大部分时间里面,都是在等待外部命令的输入,同时却选中芯片,产生了多余的功耗,此“不关心片选”技术,就是在 Nand Flash 的内部的相对快速的操作(读或写)完成之后,就取消片选,以节省系统功耗。待下次外部命令 / 数据 / 地址输入来的时候,再选中芯片,即可正常继续操作了。这样,整体上,就可以大大降低系统功耗了。

:Nand Flash 的片选与否,功耗差别会有很大。如果数据没有记错的话,我之前遇到我们系统里面的 nand flash 的片选,大概有 5 mA 的电流输出呢,要知道,整个系统优化之后的待机功耗,也才 10 mA 左右的。

 

【带 EDC 的拷回操作以及 Sector 的定义( Copy-Back Operation with EDC & Sector Definition for EDC )】

Copy-Back 功能,简单的说就是,将一个页的数据,拷贝到另一个页。

如果没有 Copy-Back 功能,那么正常的做法就是,先要将那个页的数据拷贝出来放到内存的数据 buffer 中,读出来之后,再用写命令将这页的数据,写到新的页里面。

Copy-Back 功能的好处在于,不需要用到外部的存储空间,不需要读出来放到外部的 buffer 里面,而是可以直接读取数据到内部的页寄存器( page register )然后写到新的页里面去。而且,为了保证数据的正确,要硬件支持 EDC Error Detection Code )的,否则,在数据的拷贝过程中,可能会出现错误,并且拷贝次数多了,可能会累积更多错误。

而对于错误检测来说,硬件一般支持的是 512 字节数据,对应有 16 字节用来存放校验产生的 ECC 数值,而这 512 字节一般叫做一个扇区。对于 2K 64 字节大小的页来说,按照 512 字节分,分别叫做 A B C D 区,而后面的 64 字节的 oob 区域,按照 16 字节一个区,分别叫做 E F G H 区,对应存放 A B C D 数据区的 ECC 的值。

Copy-Back 编程的主要作用在于,去掉了数据串行读取出来,再串行写入进去的时间,所以,而这部分操作,是比较耗时的,所以此技术可以提高编程效率,提高系统整体性能。

 

【多片同时编程 (Simultaneously Program Multi Plane)

对于有些新出的 Nand Flash ,支持同时对多个片进行编程,比如上面提到的三星的 K9K8G08U0A ,内部包含 4 (Plane) ,分别叫做 Plane0 Plane1 Plane2 Plane3 . 由于硬件上,对于每一个 Plane ,都有对应的大小是 2048+64=2112 字节的页寄存器( Page Register ),使得同时支持多个 Plane 编程成为可能。 K9K8G08U0A 支持同时对 2 Plane 进行编程。不过要注意的是,只能对 Plane0 Plane1 或者 Plane2 Plane3 ,同时编程,而不支持 Plane0 Plane2 同时编程。

 

【交错页编程( Interleave Page Program )】

多片同时编程,是针对一个 chip 里面的多个 Plane 来说的,

而此处的交错页编程,是指对多个 chip 而言的。

可以先对一个 chip ,假设叫 chip1 ,里面的一页进行编程,然后此时, chip1 内部就开始将数据一点点写到页里面,就出于忙的状态了,而此时可以利用这个时间,对出于就绪状态的 chip2 ,也进行页编程,发送对应的命令后, chip2 内部也就开始慢慢的写数据到存储单元里面去了,也出于忙的状态了。此时,再去检查 chip1 ,如果编程完成了,就可以开始下一页的编程了,然后发完命令后,就让其内部慢慢的编程吧,再去检查 chip2 ,如果也是编程完了,也就可以进行接下来的其他页的编程了。如此,交互操作 chip1 chip2 ,就可以有效地利用时间,使得整体编程效率提高近 2 倍,大大提高 nand flash 的编程 / 擦写速度了。

 

【随机输出页内数据( Random Data Output In a Page )】

在介绍此特性之前,先要说说,与 Random Data Output In a Page 相对应的是,普通的,正常的, sequential data output in a page

正常情况下,我们读取数据,都是先发读命令,然后等待数据从存储单元到内部的页数据寄存器中后,我们通过不断地将 RE#(Read Enale ,低电平有效 ) 置低,然后从我们开始传入的列的起始地址,一点点读出我们要的数据,直到页的末尾,当然有可能还没到页地址的末尾,就不再读了。所谓的顺序( sequential )读取也就是,根据你之前发送的列地址的起始地址开始,每读一个字节的数据出来,内部的数据指针就加 1 ,移到下个字节的地址,然后你再读下一个字节数据,就可以读出来你要的数据了,直到读取全部的数据出来为止。

而此处的随机( random )读取,就是在你正常的顺序读取的过程中,先发一个随机读取的开始命令 0x05 命令,再传入你要将内部那个数据指针定位到具体什么地址,也就是 2 cycle 的列地址,然后再发随机读取结束命令 0xE0 ,然后,内部那个数据地址指针,就会移动到你所制定的位置了,你接下来再读取的数据,就是从那个制定地址开始的数据了。

nand flash 数据手册里面也说了,这样的随机读取,你可以多次操作,没限制的。

请注意,上面你所传入的地址,都是列地址,也就是页内地址,也就是说,对于页大小为 2K nand flash 来说,所传入的地址,应该是小于 2048+64 2112 的。

不过,实际在 nand flash 的使用中,好像这种用法很少的。绝大多数,都是顺序读取数据。

 

【页编程】

Nand flash 的写操作叫做编程 Program ,编程,一般情况下,是以页为单位的。

有的 Nand Flash ,比如 K9K8G08U0A ,支持部分页编程,但是有一些限制:在同一个页内的,连续的部分页的编程,不能超过 4 此。一般情况下,很少使用到部分页编程,都是以页为单位进行编程操作的。

 

一个操作,用两个命令去实现,看起来是多余,效率不高,但是实际上,有其特殊考虑,

至少对于块擦除来说,开始的命令 0x60 是擦除设置命令 (erase setup comman) ,然后传入要擦除的块地址,然后再传入擦除确认命令( erase confirm command 0xD0 ,以开始擦除的操作。

这种,分两步:开始设置,最后确认的命令方式,是为了避免由于外部由于无意的 / 未预料而产生的噪音,比如,由于某种噪音,而产生了 0x60 命令,此时,即使被 nand flash 误认为是擦除操作,但是没有之后的确认操作 0xD0 nand flash 就不会去擦除数据,这样使得数据更安全,不会由于噪音而误操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值