-
nand flash
裸板驱动,介绍的比较精辟
/u3/
96362/showart_211
NAND
Flash
的驱动程序设计:
/html/99/
1.
硬件特性:【
Flash
的硬件实现机制】
Flash
全名叫做
Flash
Memory
,属于非易失性存储设备
(Non-
volatile Memory Device)
,与此相对应的是易失
性存储设备
(Volatile Memory Device)
。关于什么是非易失性
/
易失性,从名字中就可以
看出,非易失性就是不容易丢
失,
数据存储在这类设备中,
p>
即使断电了,
也不会丢失,
这类设备,
p>
除了
Flash
,
还有其他比较常见的入硬盘,
ROM
等,
与此相对的,易失性就是断电了,数据就丢失了,比如大家常用的内存,不论是以前的
SDRAM
,
DDR SDRAM
,还
是
现在的
DDR2
,
< br>DDR3
等,
都是断电后,
数据
就没了。
Flash
的内部存储是
MO
SFET
,
里面有个悬浮门
(Floa
ting Gate)
,
是真正存储数据的单元。在
Flash
之前,紫外线可擦除
(uv-eras
able)
的
EPROM
,就已经采用
用
Floating
Gate
存储
数据这一技术了。
数据在
F
lash
内存单元中是以电荷
(electrical cha
rge)
形式存储的。
存储电荷的多少,
取决于图中的外部门
(
external
< br>gate
)所被施加的电压,其控制了是向存储单元中冲入电荷还是使其释放电荷
。而数据的表示,以所存储的电荷的电压
是否超过一个特定的阈值
Vth
来表示。
【
SLC
和
MLC
的实现机制】
Nand Flash
按照内部存储
数据单元的电压的不同层次,也就是单个内存单元中,是存储
1
位数据,还是多位数据,可以分为
SLC
和
MLC
:
1.
SLC
,
Single Level Cell:
单个存储单元,只存储一位数据,表示成
1
或
p>
0.
就是上面介绍的,对于数据的表示,单个存储单元中内部所存
储电荷的电压,和某个特定的阈值电压
Vth
,相比,如果
p>
大于此
Vth
值,就是表示
1
,反之,小于
Vth
,就表
示
0.
对于
nand Flash<
/p>
的数据的写入
1
,就是控制
External Gate
去充电,使得存储的电荷够多,超过阈值
Vth
,就表示
1
了
。而对于写入
0
,就是将其放电,电荷减少到小于
Vth
,就表示
0
了。
p>
关于为何
Nand Flash
不能从
0
变成
1
,
我的理解是,
物理上来说,
是可以实现每一位的,
从
0
变
成
1
的,
但是实际上,
对于实际的物理实现,出于效率的考虑,如果对于,每一个存储单元都能单独控制,即,
0
变成
1
就是,对每一个存储
单元单独去充电,所需要的硬件实现就很复杂和昂贵,同时,所进行对块擦除的操作,也
就无法实现之前的,一闪而过
的速度了,也就失去了
Flash
的众多特性了。
2.
MLC
,
Multi Level
Cell
:
与
SLC
相对应,就是单个存储单元,可以存储多个位,比如
2
位,
4
位等。其实现机制,说起来比较
简单,就是,通
过控制内部电荷的多少,分成多个阈值,通过控制里面的电荷多少,而达
到我们所需要的存储成不同的数据。比如,假
设输入电压是
Vi
n
=
4V
(实际没有这样的电压,此处
只是为了举例方便),那么,可以设计出
2
的
< br>2
次方=
4
个阈值,
1/4
的
Vin
=
1V
,
2/4
的
p>
Vin
=
2V
,<
/p>
3/4
的
Vin
=
3V
,
Vin
=
4V
,分别表示
2
位数据
00
,
01
,
10
,
11
,对于写入数
据,就是充电,通过控制内部的电荷的多少,对应表示不同的
数据。
对于读取,则是通过对应的内部的电流(与
Vth
成反比),然后通过一系列解码电路完成读取,解析出所存储的数据
。
这些具体的物理实现,都是有足够精确的设备和技术,才能实现精确的数据写入和读出
的。单个存储单元可以存储
2
位
数据的
,称作
2
的
2
次方=
4 Level
Cell
,而不是
2 Level Cell
< br>,这点,之前差点搞晕了。。。,同理,对于新出的单
个存储单元可以存储
4
位数据的,称作
2
的
4
次方=
16 Level
Cell
。
【关于如何识别
SLC
还是
MLC
】
Nand
Flash
设计中,有个命令叫做
Read ID
,读取
ID
,意思是读取芯片的
ID
,就
像大家的身份证一样,这里读取的
ID
中,是读取好几个字节,一般最少是
4
个,新的芯片,支持
5
个甚至更多,从这
些字节中,可以解析出很多相关的信息,比如此
Nand Flash<
/p>
内部是几个芯片(
chip
)所组成的,
每个
chip
包含了几
片(
Plane
),每一片中的页大小,块大小,等等。在这些信息中,其中有
一个,就是识别此
flash
是
SLC
还是
MLC
。
下面这个就是最常见的
Nand Flash
的
datasheet
中所规定的,第
3
个字节,
3rd byte
,所表示的信息,其中就有
SLC/MLC
的识别信息:
/html/00/
上图是常见的
Nand Flash
所
拥有的引脚(
Pin
)所对应的功能,简单翻译如下:
1. I/O0 ~ I/O7
:
用于输入地址
/
数据
/
命令,输出数据
2.
CLE
:
Command Latch Enable
,命令锁存使能,在输入命令之前,要先在模式寄存器中,设置
CLE<
/p>
使能
3.
ALE
:
Address Latch Enable
,地址锁存使能,在输入地址之前,要先在模式寄存器中,设置
ALE<
/p>
使能
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,
就绪
/
p>
忙
,
主要用于在发送完编程
/
擦除命令后
,
检测这些操作
是否完成
,
忙
,
表示编程
/
擦除操作仍在进行中
,<
/p>
就绪表示操作完成
.
9.
Vcc
:
Power
,电源
10. Vss
:
G
round
,接地
11.
N.C
:
Non-
Connection,
未定义,未连接。
[
小常识
]
在数据
手册中,你常会看到,对于一个引脚定义,有些
字母上面带一横杠的
,那是说明此引脚
/
信号是低电平有效,
< br>比如你上面看到的
RE
头上有个横线,就是说明,此
p>
RE
是低电平有效,此外,为了书写方便,
在字母后面加
“
#
”
< br>,也
是表示低电平有效,比如我上面写的
CE
#;如果字母头上啥都没有,就是默认的高电平有效,比如上面的
CLE<
/p>
,就是
高电平有效。还有的是在
字母前面
加个小
n
,
例如
nRE,
这也是
表示低电平有效
的。
【为何需要
ALE
< br>和
CLE
】突然想明白了,
Na
nd Flash
中
,
为何设计这么多
的命令
,
把整个系统搞这么复杂的原因了
:
比如命令锁存使能
(Command Latch
Enable, CLE)
和地址锁存使能
(Address
Latch Enable
,
ALE)
,
那是因为,
Nand
Flash<
/p>
就
8
个
I/O<
/p>
,而且是复用的,也就是,可以传数据,也可以传地址,也可以传命令,为了区分你当前传
入的到底
是啥,所以,先要用发一个
CLE
(或
ALE
)命令,告诉
nand
Flash
的控制器一声,我下面要传的是命令(或地址),
这
样,里面才能根据传入的内容,进行对应的动作。否则
,nand flash
内部
,
怎么知道你传入的是数据
,
还是地址
,
还是命
令啊
,
也就无法实现正确的操作了
.
【
Nand Fla
sh
只有
8
个
I/O
引脚的好处】
1.
减少外围引脚:相对于并口
(Parellel)
的
Nor Flash
的
4
8
或
52
个引脚来说,的确是大大减小
了引脚数目,这
样封装后的芯片体积,就小很多。现在芯片在向体积更小,功能更强,功
耗更低发展,减小芯片体积,就是很大的优势。
同时,减少芯片接口,也意味着使用此芯
片的相关的外围电路会更简化,避免了繁琐的硬件连线。
2.
提高系统的可扩展性,因为没有像其他设备一样用物理大小对应的完全数目的
addr
引脚,在芯片内部换了芯片
的大小等的改
动,对于用全部的地址
addr
的引脚,那么就会引起这些引脚
数目的增加,比如容量扩大一倍,地址空间
/
寻址空间扩大一倍
,
所以,
地址线数目
/addr
引脚数目,
就要多加一个,
而对于统一用
p>
8
个
I/O
的引脚
的
Nand Flash
,
由于对外提
供的都是统一的
8
个引脚,内部的芯片大小的变化或者其他的变
化,对于外部使用者
(
比如编写
nan
d flash
驱动的人
)
来说,不需
要关心,只是保证新的芯片,还是遵循同样的接口,同样的时序,同样的命令,就可以了。这样
< br>就提高了系统的扩展性。
【
Nand flash
的一些典型<
/p>
(typical)
特性】
1.
页擦除时间是
200us
,有些慢的有
800us
。
2.
块擦除时间是
1.5ms.
p>
3.
页数据读取到数据寄存器的时间一般是
20us
。
4.
串行访问(
Serial acc
ess
)读取一个数据的时间是
25ns
,而一些旧的
nand flash
是
30ns
,甚至是
50ns
。
5.
输入输出端口是地址和数据以及命令一
起
multiplex
复用的。
以前老的
Nand Flash
,编程
/
擦除时间比较短,比如
K9G8G0
8U0M
,才
5K
次,而后来很多
p>
flash
的编程
/
擦除的寿命,最多允许的次数,以前的
nand flash
多数是
10K
次,也就是
1
万次,而现在很多新的
nand flash
,
技
术提高了,
比如,
Micron
p>
的
MT29F1GxxABB
,
Numonyx
的
NAND04G-B2D/NA
ND08G-BxC
,
都可以达到
10
0K
,
也就是
10
万次的编程
/
擦除。和之前常见的
Nor Flash
达到同样的使用寿命了。
6. 48
引脚的
TSOP1(K9F
1208UOM)
封装或
52
引脚的
ULGA
封装
【
Nand
Flash
中的特殊硬件结构】
由于
nand flash
相对其他常
见设备来说,比较特殊,所以,特殊的设备,也有特殊的设计,所以,有些特殊的硬件特
性,就有必要解释一下:
1.
页寄存器(
Page
Register
):由于
Nand Flash
读取和编程操作来说,一般最小单位是页,所以,
nand flash
p>
在硬件设计时候,就考虑到这一特性,对于每一片,都有一个对应的区域,专门用于存放,将
要写入到物理存储单元中
去的或者刚从存储单元中读取出来的,
一页的数据,
这个数据缓存区,
本质上就是一个
buffer
,
但是只是名字叫法不同,
datasheet
里面叫做
Page Regis
ter
,此处翻译为页寄存器,实际理解为页缓存,更为恰当些。而正是因为有些人不了
解此内部结构,才容易产生之前遇到的误解:以为内存里面的数据,通过
Nand Flash
的
FIFO
,写入到
Nand Flash
里面去,就以为立刻实现了
实际数据写入到物理存储单元中了。而实际上,只是写到了这个页缓存中,只有等你发了对
应的编程第二阶段的确认命令
0x10
之后,实际的编程动作
才开始,才开始把页缓存中的数据,一点点写到物理存储单
元中去。这也是为什么发完命
令
0x10
之后需要等待一段时间的原因。
所以,简单总结一下就是,对于数据的流向
,实际是经过了如下步骤:
图
4
Nand Flash
读写时的数据流向
【
Nand
Flash
中的坏块
(Bad
Block)
】
Nand Flas
h
中,一个块中含有
1
个或多个位是坏
的,就成为其为坏块。
坏块的稳定性是无法保证的,也就是说
,不能保证你写入的数据是对的,或者写入对了,读出来也不一定对的。而正常
的块,肯
定是写入读出都是正常的。
坏块有两种:
(
1
)一种是出厂的时候,也就是,你买到的新的,还没用过的
Nand Flash
,就可以包含了坏块。此类出厂时就有的
坏块,被称作
factory (masked)bad
block
或
initial bad/invalid bl
ock
,在出厂之前,就会做对应的标记,标为坏
块。
具体标记的地方是,对于现在常见的页大小为
2K
的
Nand Flash
,是块中
第一个页的
oob
起始位置(关于什么是页和
< br>oob
,下面会有详细解释)的第
1
个字节(旧的小页面,
pagesize
是
512B
甚至
256B
的
p>
nand flash
,坏块标记是第
6<
/p>
个字节),如果不是
0xFF
,就说明是
坏块。相对应的是,所有正常的块,好的块,里面所有数据都是
0xFF
的。
(
2
< br>)第二类叫做在使用过程中产生的,由于使用过程时间长了,在擦块除的时候,出错了,说明此块坏了,也 要在程
序运行过程中,发现,并且标记成坏块的。具体标记的位置,和上面一样。这类块
叫做
worn-out bad
block
。
对于坏块的管理,在
Linux
系统中,叫做坏块管理(<
/p>
BBM
,
Bad Block Mana
gment
),对应的会有一个表去记录好
块,坏块的信息,以
及坏块是出厂就有的,还是后来使用产生的,这个表叫做坏块表(
BBT
,
Bad Block Table
)。在
Linux
内核
MTD
架
构下的
Nand Flash
驱动,和
Uboot
中
Nand Flash
驱
动中,在加载完驱动之后,如果你没有加入
参数主动要求跳过坏块扫描的话,那么都会去
主动扫描坏块,建立必要的
BBT
的,以备后面坏块管理所使用
。(这样
每次使用之之前,都会自动扫描一下,建立
BBT
p>
,这样就可以跳过怀块进行别的方面的处理了)
而关于好块和坏块,
Nand
Flash
在出厂的时候,会做出保证:
1.
关于好的,可以使用的块的数目达到一定的数目,比如三星的
< br>K9G8G08U0M
,整个
flash
一共有
4096
个块,出厂
的
时候,保证好的块至少大于
3996
个,也就是意思是,你新买
到这个型号的
nand flash
,最坏的可能,有
3096
-
3996
=
100
个坏块。不过,事实上,现在出厂时的坏块,比较少,绝
大多数,都是使用时间长了,在使用过程中出现
的。
2.
保证第一个块是好的,并且一般相对来说比较耐用。做此保证的主要
原因是,很多
Nand Flash
坏块管理方法中,就
是将第一个块,用来存储上面提到的
BBT
,
否则,都是出错几率一样的块,那么也就不太好管理了,连放
BBT
的地方,
都不好找了,
^_^
。一
般来说,不同型号的
Nand
Flash
的数据手册中,也会提到,自己的这个
nand f
lash
,最多允
许多少个坏块。就比如上面提到的,三星的<
/p>
K9G8G08U0M
,最多有
100<
/p>
个坏块。
对于坏块的标记,本质上,也
只是
对应的
flash
上的某些字节的
数据是非
0xFF
而已,所以,只要是数据,就是可以读取和写
入的。也就意味着,可以写
入其他值,也就把这个坏块标记信息破坏了。对于出厂时的坏
块,一般是不建议将标记好的信息擦除掉的。
uboot
中有<
/p>
个命令是
“nand scrub”
就可
以将块中所有的内容都擦除了,包括坏块标记,不论是出厂时的,还是后来使用过程中出
现而新标记的。一般来说,不建议用这个。不过,我倒是经常用,其实也没啥大碍,呵呵。
最好用
“nand
erase”
只擦除好的块,对于已经标记坏块的块,不擦除。
【
nand Flash
中页的访问顺
序】在一个块内,对每一个页进行编程的话,必须是顺序的,而不能是随机的。比如,一
个块中有
128
个页,那么你只能先对
page0
编程,再对
page1
编程
,。。。。,而不能随机的,比如先对
page3
,
再
page1
,
page
2.
,
page0
,
< br>page4
,
.
。。。
【片选无关
(CE
don’t
-care)
技术】没明白什么意思?很多
Nand flash
支持一个叫做
CE do
n’t
-care
的技术,字面意
思就
是,不关心是否片选,那有人会问了,如果不片选,那还能对其操作吗?答案就是,这个技术,主要用在当时是不
需要选中芯片却还可以继续操作的这些情况:在某些应用,比如录音,音频播放等应用中
,外部使用的微秒(
us
)级的
时钟周
期,此处假设是比较少的
2us
,在进行读取一页或者对页编程
时,是对
Nand
Flash
操作,这样的串行(
Serial
Access
)访问的周期都是
20/30/50ns
,都是纳秒(
ns
)级的,此处假设是
50ns
,当你已经发了对应的读或写的命令
< br>之后,接下来只是需要
Nand Flash
内部去自己
操作,将数据读取或写入进去到内部的数据寄存器中而已,此处,如果
可以把片选取消,
CE#
是低电平有效,取消片选就是拉高电平,这样会在下一个
外部命令发送过来之前,即微秒量级的
时间里面,即
2us
p>
-
50ns≈2us
,这段时间的取消片选
,可以降低很少的系统功耗,但是多次的操作,就可以在很大程
度上降低整体的功耗了。
总结起来简单解释就是:由于某些外部应用的频率比较低,
<
/p>
【读(
read
)操作过程详解】
以最简单的
read
操作为例,解释如何理解时序图,以及将时序图中
的要求,转化为代码。
解释时序图之前,让我们先要搞清楚,我们要
做的事情:那就是,要从
nand flash
的某个页里面,
读取我们要的数据。
要实现此功能,会涉及到几部分的知识,至少很容易想到的就是:需
要用到哪些命令,怎么发这些命令,怎么计算所需
要的地址,怎么读取我们要的数据等等
。
下面,就一步步的解释,需要做什么,以及如何去做:
1.
需要使用何种命令
首先,是要了解,对于读取数据,要用什么命令。
下面是
datasheet
中的命令集合:
-
-
-
-
-
-
-
-
-
上一篇:船舶专业简写
下一篇:CAD电气符号及常用电缆