NAND FLASH
NAND Flash
以Micron公司的MT29F2G08为例介绍NAND Flash原理和使用。
1. 概述
MT29F2G08使用一个高度复用的8-bit总线(I/O[7:0])来数据传输、地址、指令。5个命令脚(CLE、ALE、CE#、WE#)实现NAND命令总线接口规程。3个附加的脚用作: 控制硬件写保护(WP#)、监视芯片状态(R/B#),和发起上电自己主动读特征(PRE-仅3V芯片支持)。注意, PRE功能不支持宽温芯片。
MT29F2G08内部有2048个可擦除的块,每一个块分为64个可编程的页,每一个页包括2112字节(2048个字节作为数据存储区,64个备用字节一般作为错误管理使用)。
每一个2112个字节的页能够在300us内编程,每一个块(64x2112=132K)能够在2ms内被擦除。片上控制逻辑自己主动进行PROGRAM和ERASE操作。
NAND的内部存储阵列是以页为基本单位进行存取的。读的时候,一页数据从内部存储阵列copy到数据寄存器,之后从数据寄存器按字节依次输出。写(编程)的时候,也是以页为基本单位的:起始地址装载到内部地址寄存器之后,数据被依次写入到内部数据寄存器,在页数据写入之后,阵列编程过程启动。
为了添加编程的速度,芯片有一个CACHE寄存器。在CACHE编程模式,数据先写入到CACHE寄存器,然后再写入到数据寄存器,一旦数据copy进数据寄存器后,编程就開始。在数据寄存器被装载及编程開始之后,CACHE寄存器变为空,能够继续装载下一个数据,这样内部的编程和数据的装载并行进行,提高了编程速度。
内部数据搬移命令(INTERNAL DATA MOVE)也使用内部CAHCE寄存器,通常搬移数据须要非常长时间,通过使用内部CACHE寄存器和数据寄存器,数据的搬移速度大大添加,且不须要使用外部内存。
2. 功能框图
3. 管脚
名称 |
类型 |
描写叙述 |
ALE |
I |
地址锁存使能。ALE为高时,在WE#下降沿,地址信息通过I/O[7:0]锁存片内的地址寄存器。假设传输的不是地址信息,ALE应该为低。 |
CE# |
I |
片选。一旦器件进入PROGRAM或ERASE操作,CE#能够变无效。 |
CLE |
I |
命令锁存使能。CLE为高时,在WE#上升沿,命令通过I/O[7:0]锁存到命令寄存器,当不传输命令时,CLE应该为低。 |
PRE |
I |
上电读使能。 |
RE# |
I |
读使能。 |
WE# |
I |
写使能。 |
WP# |
I |
写保护。当为低时候,全部的PROGRAM和ERASE都被禁止。 |
I/O[7:0] |
I/O |
数据输入/输出。传输命令、数据、地址。仅在读操作时,数据是输出。 |
R/B#, R/B2 |
O |
准备好/忙。集电极开路输出。外部须要接上拉电阻,这个脚表示芯片正在进行PROGRAM或ERASE操作。在读操作期间,表示数据正从阵列中传输到串行数据寄存器中,一旦这些操作完毕,R/B#回到High-Z状态。 |
Vcc |
电源 |
电源 |
Vss |
地 |
地 |
4. 寻址
Block地址和页地址 = 实际的页地址,希望通过这个图,我们能理解块、页、块地址,页地址,列地址,备份空间,备份地址
Cycle |
I/O7 |
I/O6 |
I/O5 |
I/O4 |
I/O3 |
I/O2 |
I/O1 |
I/O0 |
1 |
CA7 |
CA6 |
CA5 |
CA4 |
CA3 |
CA2 |
CA1 |
CA0 |
2 |
LOW |
LOW |
LOW |
LOW |
CA11 |
CA10 |
CA9 |
CA8 |
3 |
RA19 |
RA18 |
RA17 |
RA16 |
RA15 |
RA14 |
RA13 |
RA12 |
4 |
RA27 |
RA26 |
RA25 |
RA24 |
RA23 |
RA22 |
RA21 |
RA20 |
5 |
LOW |
LOW |
LOW |
LOW |
LOW |
LOW |
LOW |
RA28 |
CAx:列地址;RAx=行地址
5. 总线操作
CLE |
ALE |
CE# |
WE# |
RE# |
WP# |
PRE# |
MODE |
|
H |
L |
L |
上升沿 |
H |
X |
X |
读模式 |
命令输入 |
L |
H |
L |
上升沿 |
H |
X |
X |
地址输入 |
|
H |
L |
L |
上升沿 |
H |
H |
X |
写模式 |
命令输入 |
L |
H |
L |
上升沿 |
H |
H |
X |
地址输入 |
|
L |
L |
L |
上升沿 |
H |
H |
X |
数据输入 |
|
L |
L |
L |
H |
下降沿 |
X |
X |
依次读和数据输出 |
|
L |
L |
L |
H |
H |
X |
X |
在读期间(忙) |
|
X |
X |
X |
X |
X |
H |
X |
在编程期间(忙) |
|
X |
X |
X |
X |
X |
H |
X |
在擦除期间(忙) |
|
X |
X |
X |
X |
X |
L |
X |
写保护 |
|
X |
X |
H |
X |
X |
0V/Vcc |
0V/Vcc |
待机 |
上电自己主动读:在上电期间,PRE为VCC,3V VCC器件自己主动传输第一页到数据寄存器,而无须要公布一个命令或地址锁存序列。在VCC达到大约2.5V的时候,内部电压检測器触发上电自己主动读功能。在第一页数据copy到数据寄存器过程中,R/B#为低,当copy结束后,R/B#变高,在RE#脉冲的作用下第一页数据能够依次输出。
6. 命令表
操作 |
周期1 |
周期2 |
在忙期间有效 |
PAGE READ |
0x00 |
0x30 |
NO |
PAGE READ CACHE MODE START |
0x31 |
- |
NO |
PAGE READ CACHE MODE START LAST |
0x3F |
- |
NO |
READ for INTERNAL DATA MOVE |
0x00 |
0x35 |
NO |
RANDOM DATA READ |
0x05 |
0xE0 |
NO |
READ ID |
0x90 |
- |
NO |
READ STATUS |
0x70 |
- |
NO |
PROGRAM PAGE |
0x80 |
0x10 |
NO |
PROGRAM PAGE CACHE |
0x80 |
0x15 |
NO |
PROGRAM for INTERNAL DATA MOVE |
0x85 |
0x10 |
NO |
RANDOM DATA INPUT for PROGRAM |
0x85 |
- |
NO |
BLOCK ERASE |
0x60 |
0xD0 |
NO |
RESET |
0xFF |
- |
YES |
7. PAGE READ,0x00-0x30
5个地址周期,确定了读出的起始地址,数据才RE#脉冲的作用下,从这个起始地址開始依次输出,直到这一页的结束。
8. RANDOM DATA READ,0x05-0xE0
随机数据读,是为了用户可以设定新的列地址,添加数据读出的灵活性,随即读模式在页读(0x00-0x30序列)后使能。这个命令的公布次数是不受限制的。但不过当前页数据的读出。
9. PAGE READ CACHE MODE START,0x31;PAGE READ CACHE MODE START LAST,0x3F
公布PAGE READ命令后,在R/B#变高后,在发送0x31命令,这时启动将数据寄存器的内容传给CACHE寄存器,然后就能够顺序从CACHE里读第一个PAGE READ命令获得数据,因为这是数据寄存器是没实用的,因此,芯片自己主动启动读下一页的PAGE READ命令,将下一页读到数据寄存器,能够看出这么做提高的读出的速度,除了第一个PAGE READ命令外,其它PAGE READ命令都是后台自己主动进行的。再最后一次使用0x3F命令,以便禁止芯片再次自己主动公布PAGE READ命令。
10. READ ID,0x90
读出厂家的芯片标识。
11. READ STATUS,0x70
读出芯片的8bit状态。能够通过RE#脉冲,重复读。
12. 编程操作
PROGRAM PAGE 0x80-0x10:
Micron NAND FLASH仅支持页的编程,在一个块以内,页必须从一个块的页最低位到这个块的页的最高位连续编程,禁止随机页地址的编程。
芯片也支持页的部分编程操作,这意味着不论什么单个位在须要一个擦除之前仅能够被编程一次,然而,这样的页能被划分成在须要一个擦除之前同意最大8个编程操作。
SERIAL DATA INPUT 0x80:
PAGE PROGRAM操作要求载入SERAIL DATA INPUT(0x80)命令进入命令寄存器,随着5个地址周期之后,串行数据通过连续的WE#周期载入到值得的起始地址,PROGRAM(0x10)命令在数据输入完毕之后被写入,内部写状态周期自己主动运行合适的编程算法,并控制全部必要的定时编程和比較操作。写比較只检測“1”是否被成功地编程为“0”了。
R/B#在阵列编程期间(tPROG)为低,在编程操作期间,仅READ STATUS和RESET命令有效,状态寄存器的Bit6反映R/B#的状态,当芯片准备好时,读Bit0的状态确定编程操作是否成功或失败,命令寄存器在新的有效命令写入之前,一直停留在读状态寄存器模式。
RANDOM DATA INPUT 0x85:
在发起数据集输入之后,能够通过RANDOM DATA INPUT命令向新的列地址写入数据。在公布0x10命令之前,能够对同一页多次使用0x85命令。
PROGRAM PAGE CACHE MODE 0x80-0x15:
CACHE编程实际上是标准的页编程命令的带缓冲编程模式,编程開始是公布SERIAL DATA INPUT(0x80)命令,随后是5个地址周期,以及页的所有或部分数据,数据copy到CACHE寄存器,然后公布CACHE WRITE(0x15)命令。数据在WE#的上升沿锁存到数据寄存器,在这个锁存期间,R/B#为低,锁存结束之后,R/B#变高,编程開始。
当R/B#变高之后,新的数据能够通过公布还有一个CACHE PROGRAM命令来写入,R/B#保持低的时候由实际的编程时间来控制,第一次等于数据从CACHE寄存器写入到数据寄存器须要的时间,之后,仅仅有数据寄存器的内容被编程进阵列之后,CACHE寄存器才干锁存到数据寄存器,全部,以后的R/B#为低的实际应该更长一些。
状态寄存器中反映CACHE R/B#的Bit6能够通过READ STATUS命令读出,以便确定什么时候,CACHE寄存器准备好接受新的数据了。
状态寄存器中反映R/B#的Bit5能够被查询,以确定什么时候当前编程周期的实际阵列编程完毕。
假设仅使用R/B#来确定编程是否完毕,那么编程序列的最后一页必须使用PROGRAM PAGE(0x10)来替代CACHE PROGRAM(0x15)。假设CACHE PROGRAM命令每次都使用,状态寄存器的Bit5必须用来确定编程是否结束。
当状态寄存器的bit6为1时,状态寄存器Bit0返回前一页的编程是否成功,当前PROGRAM操作的成功与否的状态是:Bit5为“1”(准备好状态)时的Bit0状态
13. 内部数据搬移
内部数据搬移须要两个命令序列,先公布一个READ FOR INTERNAL DATA MOVE(0x00-0x35),然后公布一个INTERNAL DATA MOVE(0x85-0x10)命令,数据搬移只支持被读数据die范围。
READ FOR DATA MOVE 0x00-0x35:先将00写到命令寄存器,然后是内部源地址(5个周期),之后,将0x35写到命令寄存器,这将起动从内存传输一页到CACHE寄存器。虽然5个周期的地址被公布,可是列地址是被忽略的。如今芯片准备接受INTERNAL DATA MOVE(0x85-0x00)命令。
INTERNAL DATA MOVE 0x85-0x10:在READ FOR INTERNAL DATA MOVE命令公布之后,以及R/B#变高,就能够公布INTERNAL DATA MOVE命令了,这个命令将CACEH寄存器内容传输到数据寄存器,然后编程到新的目标地址,再INTERNAL DATA MOVE命令以及地址序列之后,R/B#变低,同一时候内部控制逻辑自己主动将数据编程到新的页,READ STATUS命令和状态寄存器的bit6能取代R/B#,以确定编程什么时候完毕。状态寄存器Bit0指示操作是否成功。在INTERNAL
DATA MOVE命令序列期间,RANDOM DATA INPUT(0x85)用来改动原始数据的一个或多个字:首先,使用0x00-0x35命令序列将数据copy到CACHE寄存器,然后,使用带要改动的数据地址的命令RANDOM DATA INTPUT(0x85),新的数据输入呈如今外部数据脚,这将copy新的数据进入CACHE寄存器。当0x10写入命令寄存器时候,原始数据+改动的数据被传输到数据寄存器。编程新的一页将開始,假设有必要RANDOM DATA INPUT命令能够在启动编程序列(0x10)之前公布多次。由于INTERNAL
DATA MOVE操作并不使用外部内存,所以ECC不可能在编程之前用来检查错误,这将可能或导致数据错误。在这样的情况下,运行多次INTERNAL DATA MOVE操作,这些位错误可能会因没有校正而积累。因为这个原因,我们强烈推荐利用INTERNAL DATA MOVE的系统使用鲁棒ECC方案。这将能够对每一个SECTOR校正2个或多个错误。
14. 块擦除操作,0x60-0xD0
一次擦除一个块。三个周期的地址A[28:18]被要求,先公布ERASE SETUP(0x60)命令,然后是三个地址周期,之后是ERASE CONFIRM(0xD0)命令。通过READ STATUS RESGISTER命令读擦除操作的状态,当bit6=1时,操作完毕,Bit0指示通过/失败条件,0表示通过。
15. 复位操作,0xFF
复位操作使芯片进入一个已知的状态,中断正在处理的命令序列。RANDOM READ、PROGRAM、ERASE命令在芯片忙状态能够被中断,正在被编程的位置或正在擦除的块的内容变无效,数据有可能会部分地被擦除或编程。命令寄存器被清除,准备好进入下一个命令。
复位后状态寄存器内容:
条件 |
状态 |
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 |
Hex |
WP#高 |
准备好 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0xE0 |
WP#低 |
准备好和写保护 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0x60 |
16. 写保护操作
写保护是为了防止不小心的编程和擦除操作。当WP#为低时候,全部的编程和擦除操作都会被禁止。
17. 错误管理
Micron NAND芯片出厂时并不保证芯片中全部的块都是好的,仅仅要2048个块中有不少于2008个完善块就觉得是合格品能够出厂。可是坏的块的存在,并不影响好的块的操作。在应用系统中应该提供坏块影射、替代、错误校正等算法就能够保证数据具有非常高的可靠性和完整性。
每一个CE#的第一个块(物理块地址是0)绝对是经过測试,是完善无缺的。这就提供了存放BOOT代码和重要信息的存储位置。
在芯片出厂之前,厂家会在每一个坏块的第一或第二页的第一个备份位置(列地址是2048)用非0xFF编程来标识坏块。
系统软件在进行不论什么擦除或编程操作之前应该检查每一个块的第一或第二页的第一个备份地址数据。这样创建一个坏块表。
经过一定时间的使用,内存的某些位置可能会不能正确地编程和擦除,为了确保数据的可靠性,应该採取一些预防措施,比方:
l 在写、擦除、或数据搬移操作之后,总是检查状态。
l 使用某些类型的错误检測纠正算法,以便能恢复某些轻微iede1错误。
l 使用坏块替代算法。
NAND FLASH的更多相关文章
- 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序
NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...
- (一)Nand FLASH 原理讲解
NAND FLASH 优势 : 可以用当硬盘 这里好像型号是 K9F2G08 基本结构: 不是很难自己看看,暂时不要看
- NAND flash sub-pages
http://www.linux-mtd.infradead.org/doc/ubi.html#L_subpage NAND flash sub-pages As it is said here, a ...
- Nand Flash,Nor Flash,CFI Flash,SPI Flash 之间的关系
前言: 在嵌入式开发中,如uboot的移植,kernel的移植都需要对Flash 有基本的了解.下面细说一下标题中的中Flash中的关系 一,Flash的内存存储结构 flash按照内部存 ...
- 硬件初始化,nand flash固化操作,系统启动简单流程
2015.3.27星期五 晴 链接脚本定义代码的排放顺序 硬件系统初始化:一:arm核初始化:(里面有指令)初始化ARM核的时候需要看arm核的手册指令:1.异常向量(最起码有个复位异常,初始化模式- ...
- 第8章 NAND FLASH控制器
8.1 NAND Flash介绍和NAND Flash控制器使用 NAND Flash在嵌入式系统中的地位与PC上的硬盘类似 NAND Flash在掉电后仍可保存 8.1.1 Flash介绍 有NOR ...
- s3c2440 移值u-boot-2016.03 第4篇 支持NAND flash 识别
1, /include/configs/smdk2440.h 中添加 #define CONFIG_CMD_NAND 编译 drivers/mtd/nand/built-in.o: In functi ...
- s3c2440 移值u-boot-2016.03 第2篇 支持Nand flash启动
1, 要求:在4K 的代码以内,完成 NOR NAND 类型判断,初始化 NAND 复制自身到 SDRAM ,重定向. 2, 在 /arch/arm/cpu/arm920t/ 文件夹里 添加一个 in ...
- Linux学习 : 裸板调试 之 配置使用NAND FLASH
关于NAND FLASH的结构是以页为单位写,以块为单位来擦除: 1Gb 为大页 page=2048Kb BLOCK=128K 512Mb 为小页 page=512byte ...
- Smart210学习记录----nand flash驱动
[详解]如何编写Linux下Nand Flash驱动 :http://www.cnblogs.com/linux-rookie/articles/3016990.html 当读写文件请求到来的时候, ...
随机推荐
- Qt新建线程的方法(四种办法,很详细,有截图)
看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...
- Delphi 进阶基础技能说明
以下讨论均基于Delphi XE8,主要是利用DELPHI新版的功能,如:Unicode,泛型,匿名函数等[XE2 后应该都支持]. 用新特性的好处是少写代码,提高效率.本博客不再讨论Delphi旧版 ...
- draw lines on ColumnChart
原文 http://blog.csdn.net/lixuekun820/article/details/5485042 Summary: Adobe 的 Flex Chart提供了很强大的功能,通过简 ...
- linux 和unix 的区别
Linux与Unix的区别 某些PC机的Unix和Linux在实现方面相类似.几乎所有的商业Unix版本都基本支持同样的软件.程序设计环境和网络特性.然而,Linux和Unix的商业版本依然存在许多 ...
- linux学习之(六)-主机名、网络IP的配置与查看
设置Linux 本机IP有一个非常好用的命令就是setup命令,在Linux终端打入setup命令就会打开Linux配置窗口,如下图: . 在打开的窗口中通过上下键选择 Network config ...
- 一个很好的用C#导出数据到Excel模板的方法
/// <summary> /// 导数据到Excel模板 /// </summary> /// <param name="tab">要输出内容 ...
- Nutch2.3分布执行过程中Mongodb中数据的变化
inject $ nutch inject /opt/nutch/runtime/local/urls/ > db.stats() { "db" : "nutch& ...
- 场景:A-->B-->C 跳转到C时,要关掉B的处理方法
场景:A-->B-->C 跳转到C时,要关掉B的处理方法:相当于从A跳转到C UIViewController *preController = [self.navigationContr ...
- 【phpcms-v9】如何实现在含有子栏目的栏目下添加内容?
对于题目的解释: 假设现在有一个一级栏目 为:栏目1 其下有二级栏目 :栏目1=>栏目11,栏目1=>栏目12,栏目1=>栏目13 同时栏目1下有文章列表 : 栏目1-----文章 ...
- mysql函数操作(5)
<?php try{ $dbh = new PDO('mysql:dbname=testdb;host=localhost', 'mysql_user', 'mysql_pwd'); }catc ...