linux下nand+flash驱动Word下载.docx

上传人:b****4 文档编号:16728540 上传时间:2022-11-25 格式:DOCX 页数:13 大小:335.53KB
下载 相关 举报
linux下nand+flash驱动Word下载.docx_第1页
第1页 / 共13页
linux下nand+flash驱动Word下载.docx_第2页
第2页 / 共13页
linux下nand+flash驱动Word下载.docx_第3页
第3页 / 共13页
linux下nand+flash驱动Word下载.docx_第4页
第4页 / 共13页
linux下nand+flash驱动Word下载.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

linux下nand+flash驱动Word下载.docx

《linux下nand+flash驱动Word下载.docx》由会员分享,可在线阅读,更多相关《linux下nand+flash驱动Word下载.docx(13页珍藏版)》请在冰豆网上搜索。

linux下nand+flash驱动Word下载.docx

单个cell大小

单个Cell成本

读耗时

单字节的编程时间

多字节的编程时间

擦除时间

功耗

低,但是需要额外的RAM

是否可以执行代码

不行,但是一些新的芯片,可以在第一页之外执行一些小的loader

即是否允许,芯片内执行(XIP,eXecuteInPlace)

位反转Bittwiddling

几乎无限制

1-3次,也称作“部分页编程限制”

也就是数据错误了?

在芯片出厂时候是否允许坏块

不允许

允许

【NandFlash的种类】

具体再分,又可以分为

1)BareNANDchips:

裸片,单独的nand芯片

2)SmartMediaCards:

=裸片+一层薄塑料,常用于数码相机和MP3播放器中。

之所以称smart,是由于其软件smart,而不是硬件本身有啥smart之处。

^_^

3)DiskOnChip:

裸片+gluelogic,gluelogic=硬件ECC产生器+用于静态的nand芯片控制的寄存器+直接访问一小片地址窗口,那块地址中包含了引导代码的stub桩,其可以从nandflash中拷贝真正的引导代码。

【Nandflash的特点】

Nandflash的操作,和其他一些常见的设备,如硬盘等,不同,其有自己特殊的方式。

其特殊就在于:

1.Nandflash的最小单位是页page,而不是其他很多设备所说的位bit。

2.写入数据之前必须先进行擦除erase操作

3.写的时候,最小单位是页page,对也进行写操作,也称作“页编程”,pageprogramming

4.擦除的最小单位是块block

5.由于物理特性,容易出错,所以无论是读还是写,都要采取检测和校验,即EDC。

6.nandflash出厂时候,就有一定坏的块block,成为换块,并且做了一定标记。

7.nandflash中有个额外的空间,叫做sparearea/oob

【sparearea/oob】

Nand由于最初硬件设计时候考虑到,额外的错误校验等需要空间,专门对应每个页,额外设计了叫做sparearea空区域,在其他地方,比如jffs2文件系统中,也叫做oob(outofband)数据。

其具体用途,总结起来有:

1. 

标记是否是坏快

2. 

存储ECC数据

3. 

存储一些和文件系统相关的数据,如jffs2就会用到这些空间存储一些特定信息

【常见NandFlash的大小及参数】

常见的nandflash的大小,由最开始的小于256M,到现在的常见的1G,2G,甚至更大。

以前的nandflash的

Pagesize页大小,多为512B+16B的oob,block大小为64*(512B+16B)=32KB+1KB

现在目前市场上见到的,绝大多数,都是新的nandfalsh,其Pagesize页大小多为2KB+64B的oob,block大小多为64pages页=64*(2K+64B)=128KB+4KB,一个nandflash中的芯片,一般含有4096个块,比如samsung的K9F4G08U0M,所以这个nandflash大小就是

4096Blocks=4096*64*(2K+64B)=512MB

即:

1Page=(2K+64)Bytes

1Block=(2K+64)Bx64Pages

=(128K+4K)Bytes

1Device=(2K+64)Bx64Pagesx4,096Blocks

=4,224Mbits=512MB

【Nandflash工作原理】

所谓工作原理,其实也就是对应对其如何操作的。

还是以上面提到的samsung的K9F4G08U0M的nandflash为例,简单描述如下:

1.nandflash定义了一些引脚,使得你可以发送命令过去,实现对nandflash的操控:

上面这些引脚,需要解释的主要是

CLE,使能,只有使能有效,你才能进行后续的操作。

只能选中了这个nand芯片,才能进行后续的读写。

ALE,在发送地址时,要锁住地址总线,才可以操作。

RE,WE,在读写之前,要对应的引脚有效,才可以进行读写的。

其他见解释皆可。

所有如上的引脚,都是驱动中,通过发送命令,具体内部控制逻辑去实现的。

而驱动开发者要关心的,是何时去发送对应的命令。

具体想要实现一操作,要何时发送什么命令才能实现,要继续看下面的datasheet中的解释:

如果想要对nandflash操作,就要根据datasheet中的规范进行,比如对页的写操作/写编程要根据这个顺序去操作:

其具体的细节,包含了哪些操作,可以看这个时序图:

从上图可以看出来,要先发80h的命令,再继续后面的操作。

这里的80h命令的含义,参考这个图表:

从这个图表,可以看到,80h就是pageprogram的第一个命令。

而时序图中的先两个col列地址,后三个row行地址,是根据下面这个图得来的:

此时才能定位到你所要操作的页,才能进行写操作。

再多说几句,上图表示了,如果想要对这个nandflash操作,读或写,需要进行3次列地址和三次的行地址,才能定位到你所要操作的地方,才能读写。

同时显示了,每次每个位,对应代表的地址位。

此处的2个列地址和3个行地址,是由硬件设计决定的。

老的nandflash由于每个页只有512B,所以,最后的操作,只需要1个列地址和3个行地址就可以定位了。

感兴趣的可以去网上下载samsung一些老的nandflash,可以对比着看,更明白些。

而每个操作,比如上面的写操作,都是需要一定时间的,其具体硬件操作所需的时间,见这个图:

此处可以看到,写一个页,即页编程,一般需要200us,最大需要700us,所以驱动开发者在开发的时候,要知道这个细节,要等待对应的时间,再去判断,是否写操作顺利完成了,才能接下来继续后面其他的操作的。

上述的具体代码实现,可以去看

drivers\mtd\nand\nand_base.c中的nand_command_lp()函数中的代码:

/*Commandlatchcycle*/

//对命令锁存,然后才能发送命令

chip->

cmd_ctrl(mtd,command&

0xff,

NAND_NCE|NAND_CLE|NAND_CTRL_CHANGE);

if(column!

=-1||page_addr!

=-1){

intctrl=NAND_CTRL_CHANGE|NAND_NCE|NAND_ALE;

//先发送2次col地址,构成整个列地址

/*Seriallyinputaddress*/

if(column!

/*Adjustcolumnsfor16bitbuswidth*/

if(chip->

options&

NAND_BUSWIDTH_16)

column>

>

=1;

chip->

cmd_ctrl(mtd,column,ctrl);

ctrl&

=~NAND_CTRL_CHANGE;

cmd_ctrl(mtd,column>

8,ctrl);

}

//再发送3次row地址,构成整个行地址

if(page_addr!

cmd_ctrl(mtd,page_addr,ctrl);

cmd_ctrl(mtd,page_addr>

8,

NAND_NCE|NAND_ALE);

/*Onemoreaddresscyclefordevices>

128MiB*/

chipsize>

(128<

<

20))

chip->

16,

NAND_NCE|NAND_ALE);

}

这样就可以定位到我们要操作的位置,进行操作了。

2.软件方面:

Linux驱动原理

具体内部很多实现,已经包含在drivers\mtd\nand\nand_base.c中了

【nandflash驱动加载识别nand类型过程】

在驱动加载的时候,会去调用:

nand_get_flash_type()

其中,就会对nand的类型和其他相关参数进行检查。

1) 

选中对应设备,如果此时只有一个nand芯片,则此步可以省略

/*Selectthedevice*/

select_chip(mtd,0);

x

2) 

发读命令,去读取设备类型代码

/*SendthecommandforreadingdeviceID*/

cmdfunc(mtd,NAND_CMD_READID,0x00,-1);

3) 

判断是哪个厂商的,哪个类型的flash

/*ReadmanufactureranddeviceIDs*/

*maf_id=chip->

read_byte(mtd);

dev_id=chip->

4) 

在事先已经定义好的nandflash类型中查找属于何种厂商和型号

/*Lookuptheflashid*/

for(i=0;

nand_flash_ids[i].name!

=NULL;

i++){

if(dev_id==nand_flash_ids[i].id){

type=&

nand_flash_ids[i];

break;

5) 

继续判断具体nandflash的各个参数,包括

芯片信息,Pagesize页大小,oobsize即oob的大小,blocksize块大小,buswidth总线宽度是8位还是16位。

如果页大小不是之前老的nand的512B,而是新的nand的2K或更大,则后面对应的发送给nandflash命令的的时候,调用的函数就由nand_command()变成nand_command_lp()了。

后者主要比前者多一发个命令:

chip->

即,多发一个列地址命令。

因为大页面(>

2KB)的寻址需要2次column,而小页面(512B)只需要1次的列地址。

具体可以参考nandflash的datasheet。

6) 

接着会做一些其他初始化操作,包括最后调用nand_set_defaults()去实现的默认函数的挂载,如果你的nandflash驱动没有实现的话,就是挂载默认的了。

【模块加载原理】

这个内容太大,此处只是简单说说。

驱动加载的功能主要是probe函数实现的,主要去识别设备的类型和各个参数,并且为设备的使用进行正常的初始化。

对应卸载时候执行的remove函数,施放对应的,之前申请的一些资源。

【MTD设备】

在Linux下,将nandFlash等设备归属到MTD设备下进行统一管理。

Mtd,即memorytechnologydeveice,即将nand看出是存储设备来管理。

之所以会这么说和这么做,是因为前面提高的nandflash和普通硬盘等设备的特殊性:

IO接口,最小单位是页,写前需擦除等,导致了,不能像平常对待硬盘等操作一样去操作nandflash,只能采取一些特殊方法,这就诞生了mtd设备的统一抽象层,将nandflash,norflash和其他类型的flash等设备,统一抽象成mtd设备来管理,根据这些设备的特点,上层实现了常见的操作函数封装,底层具体的内部实现,就需要驱动设计者自己来实现了。

MTD设备和硬盘设备之前的区别

HARDdrives

MTDdevice

连续的扇区

连续的可擦除块

扇区都很小(512B,1024B)

可擦除块比较大(32KB,128KB)

主要通过两个操作对其维护操作:

读扇区,写扇区

主要通过三个操作对其维护操作:

从擦除块中读,写入擦除块,擦写可擦除块

坏快被重新映射,并且被硬件隐藏起来了(至少是在如今常见的LBA硬盘设备中是如此)

坏的可擦除块没有被隐藏,软件中要处理对应的坏块问题。

HDD扇区没有擦写寿命超出的问题。

可擦除块是有擦除次数限制的,大概是104-105次.

【Linux下nandflash驱动编写步骤简介】

了解硬件的nandflash的各个参数和工作原理

具体参考nandflash的datasheet,主要包括,自己nandflash的厂商,型号等。

Nandflash的页大小,oob大小,块大小,位宽8bit还是16bit。

工作原理,上面已经做了一定描述,不清楚的,可以参考datasheet,多看看,就会明白很多。

按照linux下驱动编写规范编写nandflash驱动,

可以参考其他已经有的驱动,比如内核源码中已经有的

drivers\mtd\nand\s3c2410.c

就是个很好的例子。

自己以其为模板,实现自己板子的nandflash驱动。

其实主要工作就是,实现

staticstructplatform_drivers3c2410_nand_driver={

.probe=s3c2410_nand_probe,

.remove=s3c2410_nand_remove,

.suspend=s3c24xx_nand_suspend,

.resume=s3c24xx_nand_resume,

.driver={

.name="

s3c2410-nand"

.owner=THIS_MODULE,

},

};

中的

XXX_nand_probe函数

XXX_nand_remove函数

XXX_nand_enable_hwecc,如果支持硬件ecc的话。

对nandflash的读写,这两个函数,实现了对nand的具体操作。

【Linux下NandFlash驱动编写简单步骤】

软件和硬件知识,都已经了解的话,由于上层的linux的mtd框架中,已经完全封装好了,对nandflash的writepage,writeoob等相关函数的实现,那么剩下的只是相对来说已经是很少量的,关于nand驱动具体内部操作方面的工作:

1.初始化

先是在nand芯片初始化的时候,对其

XXX_nand_init_chip()

给对应的芯片chip赋给对应的

XXX_nand_read_buf和XXX_nand_write_buf等函数:

chip->

cmd_ctrl=XXX_nand_hwcontrol;

dev_ready=XXX_nand_devready;

read_buf=XXX_nand_read_buf;

write_buf=XXX_nand_write_buf;

以实现后续的对nand芯片的操作。

然后根据ecc类型,赋给对应的ecc的校验与纠错函数:

ecc.hwctl=XXX_nand_enable_hwecc;

ecc.calculate=XXX_nand_calculate_ecc;

实现上面提到的对应的各个函数,关于如何实现,参考一下其他nand驱动,就会理解很多了。

4. 

驱动测试,参考具体的ldd3(LinuxDeviceDriverversion3)的测试相关部分内容。

说得很乱,希望对大家有些帮助。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 中考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1