-
Nand Flash
驱动详解
1 nand_chip
结构
位于
in
cludelinuxmtdnand.h
,是
NandFla
sh
驱动的一个核心数据结构。
?
IO_ADDR_R/IO_AD
DR_W
:
读
写
Flash
的
地
址
< br>,
本
系
统
中
,
该
地
址
为
0x40000000
(
CS3
)
?
read_byte
/ write_byte
:读写字节的函数,根据数据总线
的不同,可分别使
用
nand_read_byte16
或
nand_read_byte
/
p>
nand_write_byte16
或
?
?
nand_write_byte
read_word
/
write_word
:读写字的函数,具体使用
nand_read_word
/
nand_write_word
实现
read_buf
/
write_buf
:读写缓存的函数,根据数据总线的不同,可分别使用
nand_read_buf16
或
nand_r
ead_buf
/
nand_write_buf16
或
nand_write_buf
实现
verify_buf
:缓存校验,验证从
Flash
中读取的内容是
否与缓存中一致,根据数
据总线的不同,可分别使用
nand_
verify_buf16
或
nand_verify_buf
实现
select_chip
:
选择芯片,
当参数为
0
时,
置
CS3
为低,
当参数为-
1
时,
置
CS3
为高。具体由
nand_select_chip
实现,其实是通过调用
hw
control
实现的。
block
_bad
:
读取指定页的
Bad
标记
(
badblockpos
处,
在使用小块
NandFlash
时,该变量为
5
,使用大块的
NandFlash
时,该变量为
0
)
,如果读到的内容为
0xFF
,则认为
该
Block
未坏。具体由
nand_
block_bad
实现。函数中用到
nand_get_de
vice
,该函数用于处理多线程同时访问
NandFlash
的互锁。
block_markba
d
:
具体由
nand_default
_block_markbad
实现,
该函数在
bbt
中将指定偏移所属块标志为坏块,并利用
wri
te_bbt
函数将其存储到
Flash
中。
最后该函数在坏块的坏块标记(
badblockpos
)处写入
0x00
,表示该块为坏块。
hwcontrol
:
执
行
命
令
< br>锁
存
(
NAND_CTL_SE
TCLE
)、
地
址
锁
存
(
NAND_CTL_SET
ALE
)
以
及
片
选
信
号
控<
/p>
制
(
NAND_CTL_CLRNCE<
/p>
、
NAND_CTL_SETNCE
)等
命令。其中由于
ALE
、
CLE
均是地址线,因此命令锁
存、地址锁存只需要改变写地址(
IO_ADDR_W
)即可,而片选信号控制需要直
接控制
PC14
管脚。具体由
at9
1sam9260ek_nand_hwcontrol
实现
dev_ready
:具体由
at91
sam9260ek_nand_ready
函数实现,该函数返回
Flash
的
R/B
脚状态。
p>
cmdfunc
:具体由
nand_command
函数实现,对于大块的
Fl
ash
,采用
nand_command_lp
实
现
。
注
意
对
于
写
命
令
,
首
先<
/p>
得
利
用
read
0/read1/readoob
命令选中目标数据块
waitfunc
:
具体由
< br>nand_wait
函数实现,
该函数根据命令的不同设
定不同的超时
时间。该函数时刻检查
R/B
管脚或状态寄存器中的
R/B
位,直到
R/B
状态进入
Ready
状态,
或总体超时。
calculate_ecc
< br>:
具体由
nand_calculate_ecc
函数实现,
该函数利用软件法计算
256
p>
字节的
3
字节
EC
C
编码。
correct_data
:具体由
nand_correct_data
函数实现,该函数检测并纠正
256
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
字节块中的
1
位错误。
enable_hwe
cc
:具体由
at91sam9260ek_nand_ena
ble_hwecc
函数实现,
使能硬件计算
< br>ECC
码
erase_cmd
:具体由
single_erase_cmd
< br>函数实现,擦除指定块。
scan_bbt
:
具体由
nand_default_bbt
p>
函数实现。
nand_default_bbt
函数在调
用
nand_scan_bbt
< br>之前,根据
options
确定
bbt
是否存在于
Flash
中,如果
不存在与
Flash
中,则将
this
->bbt_td
设置为
NULL
,在
nand_scan_bbt
中自然会创建一个
this->bbt
。否则将从
Flash
中读取
bbt
。
eccmode
:
ECC
的计算方法,现在采用
NAND_ECC_SOFT
,意指
软件运算,即
采用
calculate_ecc
进行运算,利用
correct_data
进行校正<
/p>
eccsize
:
ECC
校准的数据长度,
现利用
c
alculate_ecc
进行校准,
数据长度固定
为
256
字节
eccbyte
:
ECC
校验码字节数,软件校准为
3
字节
eccsteps
:
ECC
校验的步骤,由于
FLASH
每页的字节数为
p>
512
字节,而
calculate_ec
c
每次仅能校验
256
字节,故需要两
步才能校验完成。
chip_delay
:等待时间,一般用于等待
Flash
的
< br>R/B
管脚
page_shi
ft
:页的地址位数,
512
字节的空
间,其该值为
9
phys_erase_shift
:
Flash
的可擦除的空间,也即是块的地址
位数
bbt_erase_shift
:
在
bbt
表中,
< br>相间隔两个内容之间的地址差的位数,
也即是块
的地址位
数
chip_shift
:芯片总的
地址位数
data_buf
:数据空
间,所占空间大小为一个页+空闲空间,共
528
字节,标记<
/p>
NAND_DATABUF_ALLOC
表示
data_buf
已被分配空间
oob_buf
:
分
配
了
一
个
块
内
所
有
页
的
空
间
部
分<
/p>
的
空
间
,
标
记
NAND_OOBBUF_ALLOC<
/p>
表示
oob_buf
已被分配空间
oobdirty
:表示
< br>oob_buf
内是否有内容,如为
0
< br>表示
oob_buf
为空(
0x
FF
)
,
为
1
表示
oob_buf
中已有内容
data_poi
:指向一个临时使用的数
据区
options
:结构的一些选
项,如
NAND_IS_AND
、
NA
ND_USE_FLASH_BBT
、
NAND_DATABU
F_ALLOC
等等
badbloc
kpos
:坏块标记的位置(
NAND_SMALL_BADB
LOCK_POS
)
numchip
s
:物理上芯片的数量(此处为
1
)<
/p>
chipsize
:芯片的容量
p>
pagemask
:页号的屏蔽位,如
16
K
的芯片,每页
512
,则此位为
p>
0x1F
pagebuf
:存储
Data_buf
内的相关的页号
autooob
:自动存储
oob
时的
oob
选项,此处该结构如下:
< br>
static struct nand_oobinfo
nand_oob_16 = {
.useecc =
MTD_NANDECC_AUTOPLACE,
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 6, 7},
.oobfree = { {8, 8} }
};
其中
eccbyte
为
ECC
校验的位数,
eccpos
为
ECC
校验所存的位号,
oobfree
为
< br>OOB
中
ECC
未使用到的字节
(起始地址+长度)
?
bbt
:指向内存中坏块表的指针
?
bbt_td
:用以
Flash
中坏块表搜索的相关描述,其结构如下:
static struct
nand_bbt_descr bbt_main_descr = {
.options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE |
NAND_BBT_2BIT
|
NAND_BBT_VERSION
|
NAND_BBT_PERCHIP
,
.offs =
8,
.len = 4,
.veroffs = 12,
.maxblocks = 4,
.pattern = bbt_pattern
};
static uint8_t bbt_pattern[] = {'B',
'b', 't', '0' };
?
bbt_md
:上述描述的镜像
?
badblock_patter
n
:寻找坏块所需要的模型,如
static struct nand_bbt_descr
smallpage_flashbased = {
.options = NAND_BBT_SCANEMPTY |
NAND_BBT_SCANALLPAGES,
.offs = 5,
.len
= 1,
.pattern =
scan_ff_pattern
};
static uint8_t scan_ff_pattern[] = {
0xff, 0xff };
OOB
中偏移位置
5
,长度为
1
,内容为
0xFF
代表是好块
?
controller
p>
:用以实现互锁操作,此处并未使用
?
priv
:暂时不知
本系统中,数据总线为
8
位
2 write_bbt
nand
_chip
中的成员变量
bbt
存的是
坏块表,其中每两位表示一个块:
?
?
?
?
该函数
首先判断
td->page
成员变量是否为
-1
,如果不是,说明
bbt
的存
储页已经确
定,否则根据
td->options
的
NAND_BBT_LASTBLOCK
选项从后
往前或从前往后搜寻
00b:
01b:
10b:
11b:
block
is good
block is marked bad due to wear
block is reserved (to protect the bbt
area)
block is factory marked bad