FatFs文件系统Nandflash驱动函数详解

时间:2024-04-10 21:07:04

FatFs文件系统Nandflash驱动函数详解

转载 2015-08-06 14:43:27

标签:nandflash驱动函数详fatfs文件系统nandfla

本文讲解FatFs文件系统 下需要的nandflash驱动函数

FatFs文件系统Nandflash驱动函数详解

1:disk_initialize()

    此函数用于nandflash的初始化,包过时钟和基本的IO初始化,以及建立LUT表。

​      显示查找表(Look-Up-Table)简称为LUT,LUT本质上就是一个RAM。它把数据事先写入RAM后,每当输入一个信号就等于输入一个地址进行查表,找出地址对应的内容,然后输出。

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

FatFs文件系统Nandflash驱动函数详解

flash芯片HY27UF081G2A

HY27UF081G2A = 128M Flash.  有1024个BLOCK,每个BLOCK包含64个PAGE,每个PAGE包含2048+64个字节,擦除的最小单位是BLOCK,编程最小单位是字节。

每个PAGE在逻辑上可以分为4个512字节扇区

简单解释就是:

1.一个nand flash由很多个块(Block)组成,

块的大小一般是

-> 128KB,

-> 256KB,

-> 512KB

此处是128KB。

2.每个块里面又包含了很多页(page)。每个页的大小,

老的nand flash,页大小是256B,512B,

这类的nand flash被称作small block,。地址周期只有4个。

对于现在常见的nand flash多数是2KB,

被称作big block,对应的发读写命令地址,一共5个周期(cycle),

更新的nand flash是4KB,

,也是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中的坏块(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中页的访问顺序】

在一个块内,对每一个页进行编程的话,必须是顺序的,而不能是随机的。比如,一个块中有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的值。

总结:

512+16

2K +64 : A B C D - E F G H区

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

在nandflash的驱动函数中,nandflash初始化时建立LUT表,具体函数如下所示

FatFs文件系统Nandflash驱动函数详解

​2、disk_read()

此函数用于从nandflash中读取一个sector(扇区)

函数结构如下所示

FatFs文件系统Nandflash驱动函数详解

​为了支持不同的存储介质 我们将disk_read()函数进行了转换 如下图所示

FatFs文件系统Nandflash驱动函数详解

​函数NAND_ReadMultiSetors()函数如下所示

FatFs文件系统Nandflash驱动函数详解

​//函数FSMC_NAND_Read()在nandflash通信接口中讲解

3、disk_write()​

FatFs文件系统Nandflash驱动函数详解

​同样为了适应不同的介质 对函数disk_write进行了转换

FatFs文件系统Nandflash驱动函数详解

​函数NAND_WriteMultiSectors()如下所示

FatFs文件系统Nandflash驱动函数详解

FatFs文件系统Nandflash驱动函数详解

FatFs文件系统Nandflash驱动函数详解

详细查阅资料/SD卡/FAT32文件系统详解.pdf​