




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、【Nand Flash驱动编写之前要了解的知识】1. 硬件特性:【Flash的硬件实现机制】Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Volatile Memory Device)。关于什么是非易失性/易失性,从名字中就可以看出,非易失性就是不容易丢失,数据存储在这类设备中,即使断电了,也不会丢失,这类设备,除了Flash,还有其他比较常见的入硬盘,ROM等,与此相对的,易失性就是断电了,数据就丢失了,比
2、如大家常用的内存,不论是以前的SDRAM,DDR SDRAM,还是现在的DDR2,DDR3等,都是断电后,数据就没了。 Flash的内部存储是MOSFET,里面有个悬浮门(Floating Gate),是真正存储数据的单元。在Flash之前,紫外线可擦除(uv-erasable)的EPROM,就已经采用用Floating Gate存储数据这一技术了。图1.典型的Flash内存单元的物理结构数据在Flash内存单元中是以电荷(electrical charge) 形式存储的。存储电荷的多少,取决于图中的外部门(external gate)所被施加的电压,其控制了是向存储单元中
3、冲入电荷还是使其释放电荷。而数据的表示,以所存储的电荷的电压是否超过一个特定的阈值Vth来表示。 【SLC和MLC的实现机制】Nand Flash按照内部存储数据单元的电压的不同层次,也就是单个内存单元中,是存储1位数据,还是多位数据,可以分为SLC和MLC:1. SLC,Single Level Cell:单个存储单元,只存储一位数据,表示成1或0.就是上面介绍的,对于数据的表示,单个存储单元中内部所存储电荷的电压,和某个特定的阈值电压Vth,相比,如果大于此Vth值,就是表示1,反之,小于Vth,就
4、表示0.对于nand Flash的数据的写入1,就是控制External Gate去充电,使得存储的电荷够多,超过阈值Vth,就表示1了。而对于写入0,就是将其放电,电荷减少到小于Vth,就表示0了。关于为何Nand Flash不能从0变成1,我的理解是,物理上来说,是可以实现每一位的,从0变成1的,但是实际上,对于实际的物理实现,出于效率的考虑,如果对于,每一个存储单元都能单独控制,即,0变成1就是,对每一个存储单元单独去充电,所需要的硬件实现就很复杂和昂贵,同时,所进行对块擦除的操作,也就无法实现之前的,一闪而过的速度了,也就失去了Flash的众多特性了。 2.
5、60; MLC,Multi Level Cell:与SLC相对应,就是单个存储单元,可以存储多个位,比如2位,4位等。其实现机制,说起来比较简单,就是,通过控制内部电荷的多少,分成多个阈值,通过控制里面的电荷多少,而达到我们所需要的存储成不同的数据。比如,假设输入电压是Vin4V(实际没有这样的电压,此处只是为了举例方便),那么,可以设计出2的2次方4个阈值, 1/4 的Vin1V,2/4的Vin2V,3/4的Vin3V,Vin4V,分别表示2位数据00,01,10,11,对于写入数据,就是充电,通过控制内部的电荷的
6、多少,对应表示不同的数据。对于读取,则是通过对应的内部的电流(与Vth成反比),然后通过一系列解码电路完成读取,解析出所存储的数据。这些具体的物理实现,都是有足够精确的设备和技术,才能实现精确的数据写入和读出的。单个存储单元可以存储2位数据的,称作2的2次方4 Level Cell,而不是2 Level Cell,这点,之前差点搞晕了。,同理,对于新出的单个存储单元可以存储4位数据的,称作 2的4次方16 Level Cell。 【关于如何识别SLC还是MLC】Nand Flash设计中,有个命令叫做Read ID,读取ID,意思是读取芯片的ID,就像大家的身份证一样,这里
7、读取的ID中,是读取好几个字节,一般最少是4个,新的芯片,支持5个甚至更多,从这些字节中,可以解析出很多相关的信息,比如此Nand Flash内部是几个芯片(chip)所组成的,每个chip包含了几片(Plane),每一片中的页大小,块大小,等等。在这些信息中,其中有一个,就是识别此flash是SLC还是MLC。下面这个就是最常见的Nand Flash的datasheet中所规定的,第3个字节,3rd byte,所表示的信息,其中就有SLC/MLC的识别信息: DescriptionI/O7I/O6I/O5 I/O4I/O3 I/O2I/O1 I/O0InternalChip Num
8、ber1248 0 00 11 01 1Cell Type2 Level Cell4 Level Cell8 Level Cell16 Level Cell 0 00 11
9、 01 1 Number ofSimultaneouslyProgrammed Pages1248 0 00 11 01 1 Interleave ProgramBetween multiple chipsNot SupportSupport
10、160;01 Cache ProgramNot SupportSupport01 表1.Nand Flash 第3个ID的含义 【Nand Flash的物理存储单元的阵列组织结构】Nand flash的内部组织结构,此处还是用图来解释,比较容易理解:图2.Nand Flash物理存储单元的阵列组织结构上图是K9K8G08U0A的datasheet中的描述。简单解释就是:1.一个nand flash由很多个块(Block)组成,块的大小一般是128KB,256KB,512KB,此处是128KB。2
11、.每个块里面又包含了很多页(page)。每个页的大小,对于现在常见的nand flash多数是2KB,更新的nand flash是4KB,这类的,页大小大于2KB的nand flash,被称作big block,对应的发读写命令地址,一共5个周期(cycle),而老的nand flash,页大小是256B,512B,这类的nand flash被称作small block,。地址周期只有4个。而块,也是Nand Flash的擦除操作的基本/最小单位。3.每一个页,对应还有一块区域,叫做空闲区域(spare area)/冗余区域(redundant area),而Linux系统中,一般叫做OOB(
12、Out Of Band),这个区域,是最初基于Nand Flash的硬件特性:数据在读写时候相对容易错误,所以为了保证数据的正确性,必须要有对应的检测和纠错机制,此机制被叫做EDC(Error Detection Code)/ECC(Error Code Correction, 或者 Error Checking and Correcting),所以设计了多余的区域,用于放置数据的校验值。页是Nand Flash的写入操作的基本/最小的单位。 【Nand Flash数据存储单元的整体架构】简单说就是,常见的nand flash,内部只有一个chip,每个chip只
13、有一个plane。而有些复杂的,容量更大的nand flash,内部有多个chip,每个chip有多个plane。这类的nand flash,往往也有更加高级的功能,比如下面要介绍的Multi Plane Program和Interleave Page Program等。比如,型号为K9K8G08U0A这个芯片(chip),内部有两个K9F4G08U0A,每个K9F4G08U0A包含了2个Plane,每个Plane是1Gb,所以K9F4G08U0A的大小是1Gb×22Gb256MB,因此,K9K8G08U0A内部有2个K9F4G08U0A,即4个Plane,总大小是4×25
14、6MB1GB。而型号是K9WAG08U1A的nand flash,内部包含了2个K9K8G08U0A,所以,总容量是K9K8G08U0A的两倍1GB×22GB,类似地K9NBG08U5A,内部包含了4个K9K8G08U0A,总大小就是4×1GB4GB。 【Flash名称的由来】Flash的擦除操作是以block块为单位的,与此相对应的是其他很多存储设备,是以bit位为最小读取/写入的单位,Flash是一次性地擦除整个块:在发送一个擦除命令后,一次性地将一个block,常见的块的大小是128KB/256KB。,全部擦除为1,也就是里面的内容全部都是0xFF了,由于是
15、一下子就擦除了,相对来说,擦除用的时间很短,可以用一闪而过来形容,所以,叫做Flash Memory。中文有的翻译为 (快速)闪存。 【Flash相对于普通设备的特殊性】1. 上面提到过的,Flash最小操作单位,有些特殊。一般设备,比如硬盘/内存,读取和写入都是以bit位为单位,读取一个bit的值,将某个值写入对应的地址的位,都是可以按位操作的。但是Flash由于物理特性,使得内部存储的数据,只能从1变成0,这点,可以从前面的内部实现机制了解到,只是方便统一充电,不方便单独的存储单元去放电,
16、所以才说,只能从1变成0,也就是释放电荷。所以,总结一下Flash的特殊性如下: 普通设备(硬盘/内存等)Flash读取/写入的叫法读取/写入读取/编程(Program)读取/写入的最小单位Bit/位Page/页擦除(Erase)操作的最小单位Bit/位Block/块 擦除操作的含义将数据删除/全部写入0将整个块都擦除成全是1,也就是里面的数据都是0xFF 对于写操作直接写即可在写数据之前,要先擦除,然后再写表2.Flash和普通设备相比所具有的特殊性注: 之所以将写操作叫做编程,是因为,flash 和之前的EPROM,EEPROM
17、继承发展而来,而之前的EEPROM(Electrically Erasable Programmable Read-Only Memory),往里面写入数据,就叫做编程Program,之所以这么称呼,是因为其对数据的写入,是需要用电去擦除/写入的,就叫做编程。 对于目前常见的页大小是2K/4K的Nand Flash,其块的大小有128KB/256KB/512KB等。而对于Nor Flash,常见的块大小有64K/32K等。在写数据之前,要先擦除,内部就都变成0xFF了,然后才能写入数据,也就是将对应位由1变成0。单片机控制Nand Flash 涉及到的算法:ECC校验,坏块管理,垃圾
18、搜集,负载均衡。Nand Flash原理分析与编程NAND Flash 在嵌入式系统中的地位与PC机上的硬盘是类似的。用于保存系统运行所必需的操作系统,应用程序,用户数据,运行过程中产生的各类数据,系统掉电后数据不会护丢失.本文主要介绍关于NAND Flash的组织结构和编写程序的方法。 在三星的NAND Flash 中,当CPU从NAND Flash开始启动时,CPU会通过内部的硬件将NAND Flash开始的4KB数据复制到称为“Steppingstone”的4KB的内部RAM中,起始地址为0,然后跳到地址
19、0处开始执行。这也就是我们为什么可以把小于4KB的程序烧到NAND Flash中,可以运行,而当大于4KB时,却没有办法运行,必须借助于NAND Flash的读操作,读取4KB以后的程序到内存中。 NAND Flash的寻址方式和NAND Flash的memory组织方式紧密相关。NAND Flash的数据是以bit的方式保存在 memory cell(存储单元)。一般情况下,一个cell中只能存储一个bit。这些cell以8个或者16个为单位,连成 bit line ,形成所谓的byte(x8)/word(x16),这就是NAND Flash的位宽。 这些Line会再组成
20、Pape(页)。然后是每32个page形成一个Block,所以一个Block(块)大小是16k.Block是NAND Flash中最大的操作单元,其中的擦除操作是以Block为单位进行擦除的,而读写和编程是以page为单位进行操作的,并且读写之前必须进行flash的擦写。我们这里以三星K9F1208U0M的NAND Flash 为例,它的大小是64MB的。 1block = 32page 1page = 512bytes(datafield) + 16bytes(oob) K9F1208U0B总共有4096 个Blocks,故我们可以知道这块flash的容量为40
21、96 *(32 *528)= 69206016 Bytes = 66 MB 但事实上每个Page上的最后16Bytes是用于存贮检验码用的,并不能存放实际的数据,所以实际上我们可以操作的芯片容量为 4096 *(32 *512) = 67108864 Bytes = 64 MB Nand Flash 物理结构图 在NAND Flash中有8个I/O引脚(IO0IO7)、5个全能信号(nWE ALE CLE nCE nRE)、一个引脚,1个写保护引脚。操作NAND Flash时,先传输命令,然后传输地址,最后读写数据。对于64MB的NAND Flash,需
22、要一个26位的地址。只能8个I/O引脚充当地址、数据、命令的复用端口,所以每次传地址只能传8位。这样就需要4个地址序列。因此读写一次nand flash需要传送4次(A7:0 A16:9 A24:17 A25)。64M的NAND Flash的地址范围为0x000000000x03FFFFFF。 一页有528个字节,而在前512B中存放着用户的数据。在后面的16字节中(OOB)中存放着执行命令后的状态信息。主要是ECC校验的标识。列地址A0-A7可以寻址的范围是256个字节,要寻址528字节的话,将一页分为了A.(1half array)B(2 half array) C(spare
23、array)。A区0255字节,B区 256-511 字节C区512527字节。访问某页时必须选定特定的区。这可以使地址指针指向特定的区实现。 在NAND Flash 中存在三类地址,分别为Block Address 、Column Address Page Address.。 Column Address 用来选择是在上半页寻址还是在下半页寻址A0A7.也就相当于页内的偏移地址。在进行擦除时不需要列地址,因为擦除是以块为单位擦除。32个Page需要5bit来表示。也就是A13:9;也就是页在块内的相对地址。A8这一位用来设置512字节的上半页,还是下半页,1表示是在上半页
24、,而2表示是在下半页。Block的地址有A25:14组成。 存储操作特点: 1.擦除操作的最小单位是块 2.Nand Flash芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除(擦除就是将相应块的位全部变为1 3 OOB部分的第六字节(即517字节)标志是否坏块,如果不是坏块该值为FF,否则为坏块 4 除OOB第六字节外,通常至少把OOB前3字节存放Nand Flash硬件ECC码 一个容量为64M(512Mbit)的NAND Flash,分为131072页,528列。(实际中由于存在spare
25、 area,故都大于这个值),有4096块,需要12bit来表示即A25:14.如果是128M(1Gbit)的话,blodk Address为A26:14.由于地址只能在IO0IO7上传送。编程时通常通过移位来实现地址的传送。传送过程如下: 第1个地址序列:传递column address,也就是NAND Flash7:0,这一周期不需要移位即可传递到I/O7:0上,而half page pointer 即A8是由操作指令决定,00h,在A区,01h在B区,指令决定在哪个half page上进行读写,而真正A8的值是不需要程序员关心的; 第2个地址序列:就是将NAND_AD
26、DR 右移9位,而不是8位,将NAND_ADDR16:9传递到I/O7:0上; 第3个地址序列:将NAND_ADDR24:17 传递到I/O7:0上; 第4个地址序列:将NAND_ADDR25传送到I/O上。 整个地址的传送过程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的话,那么block address 最高位只到bit24,因此寻址只需要3步,就可以完成。 在进行擦除操作时由于是以块进行擦除,所以只需要3个地址序列,也就是只传递块的地址,即A14:25。 NAND Flash地址的计算: Column Ad
27、dress 翻译过来是列地址,也就是在一页里的偏移地址。其实是指定Page上的某个Byte,指定这个Byte,其实也就是指定此页的读写起始地址。 Page Address:页地址。页的地址总是以512Bytes对齐的,所以它的低9位问题0,确定读写操作在NAND Flash中的哪个页进行。 当我们得到一个Nand Flash地址addr时,我们可以这样分解出Column Address和Page Address。 Columnaddr = addr % 512 / column address Pageaddr = addr>>9 / pag
28、e address 也就是一个Nand Flash地址的A0-A7是它的column address ,A9A25是它的Page Address,地址A8被忽略。 现在假设我要从Nand Flash中的第5000字节处开始读取1024个字节到内存的0x30000000处,我们这样调用read函数 NF_Read(5000, 0x30000000,1024); 我们来分析5000这个src_addr. 根据 column_addr=src_addr%512; page_addr
29、ess=(src_addr>>9); 我们可得出column_addr=5000%512=392 page_address=(5000>>9)=9 于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的NF_read函数将这样发送命令和参数 column_addr=5000%512; page_address=(5000>>9); NF_CMD=0x01; /要从2nd half开始读取 所以要发送命令0x01 NF_ADDR= column_addr &0xff
30、; /1st Cycle A7:0 NF_ADDR=page_address& 0xff NF_ADDR=(page_address>>8)&0xff; /3rd.Cycle A24:17 NF_ADDR=(page_address>>16)&0xff; /4th.Cycle A25 向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了. 我用下面的代码进行数据的读取. for(i=column_addr;i<512;i
31、+) *buf+=NF_RDDATA(); 每当读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte).1、关于NAND FLASH 的坏块管理就现在的NAND FLASH ,有串口和并口两种,并口就是48PIN的数据的输入和输入公用IO的串口的就是使用SPI接口的NAND FLASH说下NAND FLASH 管理的核心思维:1 识别坏块,标记坏块,2 如何保存坏块信息3 交换区概念4 保留去概念1,NANDFLASH 的工艺不能保证写进去的每个块里面的数据,和读出来的数据一致,所以是存在坏块的,而NAND FLASH
32、的数据组织结构是这样的,由N个块组成,而块由M个PAGE组成+MXSPARE区比如 K9F1G08U0D 以这个片子为例子,BLOCK 大小为 128K 用户可以写的,实际大小为 128K + 64*4*16至于后面64*4*16的意思是这样的, 因为该片子每个PAGE的大小为2048 也就是2K,而因为NAND 存在坏块,所以,在每写512个字节后,都会产生一个校验码,而这个校验码用来标记,该块是坏块还是可以正常使用的,当然这个512是针对大页的NAND FLASH,小页的话是每256个字节产出一个校验码,当然现在这样的小页的NAND FLASH很少见了,老了,即使有,也是拆机弄下来的,坏块
33、的识别的话,这几种,并口的:一个是可以根据ECC校验算法来,判断是否为坏块,具体算法可以去百度查查,一个是可以判断在写玩数据之后,来判断SPARE数据区域来判断段坏块,而对于小页和大页的有区别小页的NANDFLASH ,比如一个页的大小为1K,那么,在读取1K后面数据的16个数据,如果第一个数据不为FF,那么标记该块为坏块,在标记的时候,可以标记的数据为全部为00,也就是在标记16个数据的时候表示为0而在标记的时候,一般标记的区域是这个块的第一个PAGE后的16个数据 串口:串口的,里面有自校验,硬件的,所以在识别的时候,可以直接装载要判断的PAGE的地址,然后去读取状态寄存器即可,
34、同样的也可以去标记坏块,标记花开的话和并口的一样2 如何保存坏块信息,坏块信息一般包括:1 ,保存坏块的信息的地址,也就是你要获得坏块信息的话,一般去哪个地址去读,可以是固定的,也可以不是固定的,不固定的花费的时间长点,管理起来复杂2,坏块信息要保存交换区的信息:这个信息是,你所使用的交换区,某个块是坏块,还是好块 后面会介绍3,保留区的地址映射状态,后面会介绍4 ,如何去标记该块是作为,保存坏块信息表格呢,至于如何保存坏块信息,很多种方法,核心就是,用特殊的数据去标记,比如,我在用来保存坏块信息表的时候,一般这样标记该块的第一个PAGE的前面八个数据是这样的,0xff55aa00,0x000
35、0000该块的最后一个PAGE ,最后8个数据是0X33445588.0XFF00FF00然后该块的倒数第二个PAGE,标记交换区的信息和保留去地址映射关系,+一个校验和而对于保存坏块信息表格所用的块,一般是3个或者5个不等,交替使用,或者也可以不交替使用,对于不交替使用的情况就是,一旦发生坏块标记的情况的话,那么3或者5个块都要被写数据,而却写的数据是一样的,有人会说,占用这么多块不是浪费,其实,对于整个芯片来说,占用这几个块,而有个坏块管理程序是值得的3 交换区概念:比如,块0 ,该块大小为128K, 在0X000-0X18000里面有数据,0x18800 - 0x20000这个有数据是文
36、件系统认为的, 而文件系统要在0x18000-0x18800这个512的范围内要写数据,那该怎么办呢,肯定要这个块个擦除掉的,如果没有交换区的话,那么擦除的话,会导致在0X000-0X18000,0x18800 - 0x20000之间的数据都会丢失的,那该怎么办呢,那就要使用交换区,交换区的作用就是这样的,如果要擦除某个块的话,那么首先要将这个块里面的数据拷贝到另外一个块里面,而这个另外一个块,称之为交换区,首先将整个块的数据,全部放到一个可以用的交换区,然后再将0这个块擦除,擦除之后0这个块里面的数据就是FF了,那么在擦除之后,在将交换区里面的数据回写到0这个块里面那么出现的情况就
37、是0X000-0X18000,0x18200 - 0x20000 这个两个区间内的数据还是原来的数据,在将原来的数据回写到0块之后,然后在将这次文件系统要写的数据写到0x18000-0x18200这个区域里面,这样既保证数据的完整性,又能将新数据写进去4保留区概念:保留区的作用就是这个,当在写数据的时候发生坏块的话,那么得将这个块的数据要保存另外一个块里面,同时要对产生的那个坏块进行标记。2、NANDFLASH坏块管理思维K9F2808U0C是16 MB×8 bit的NAND Flash,共有1 024个Block,1 Block=16 KB,32 Page/Block,1 Page
38、=528 B=(512 B+16 B),其中16 B为备用区,主要存放NAND Flash出厂坏块标记、ECC校验码以及用户自定义区。K9F2808U0C地址空间是24 bit,分三个周期依次送入NAND Flash的地址锁存器。本文使用的地址均为字节地址,数据类型为DWORD(4 B)。 将K9F2808U0C的存储空间划分为四个区:坏块映射表存放区、交换块区、坏块映射区和实际数据存放区。文件系统管理的空间就是实际的数据存放空间,如图2所示。2.2 各分区宏定义 #define FLASH_BLOCK_SIZE
39、; 0x40000 /16 KB/Block #define FLASH_PAGE_SIZE 0x200 /512 B/Page #define FLASH_SECTOR_SIZE 0x200/1Page=1Sector(only K9F2808U0C) #define FLASH_BLOCKS_TABLE 3/坏块映射
40、表存放块数 #define FLASH_SWAP_BLOCKS 5 /交换区的块数 #define FLASH_BAD_BLOCKS_REMAP 50/坏簇重映区的块数 #define FLASH_MAX_ADDR 0xFFFFFF/Flash最大字节地址 各分区首地址计算公式: FLASH_BLOCK_TABLE_ADD
41、R=FLASH_MAX_ADDR+1-3*FLASH_BLOCK_SIZE); FLASH_SWAP_BLOCK_ADDR=(FLASH_BLOCK_TABLE_ADDR-5*FLASH_BLOCK_SIZE); FLASH_BAD_BLOCK_REMAP_ADDR=(FLASH_SWAP_BLOCK_ADDR-50*FLASH_BLOCK_SIZE); FLASH_MAX_SECTOR_ADDR=(FLASH_MAX_ADDR-3*FLASH_BLOCK_TABLE_ADDR-5*FL
42、ASH_SWAP_BLOCK_ADDR-50*FLASH_BAD_BLOCK_REMAP_ADDR);文件系统管理的最大字节地址。 任意地址Addr: 所在块地址:Addr&(FLASH_BLOCK_SIZE-1); 块内偏移地址:Addr&(FLASH_BLOCK_SIZE-1); 块中的页:(Addr&(FLASH_BLOCK_SIZE-1)/FLASH_PAGE_SIZE;2.3 分区功能设计
43、160;坏块映射区存放复制3份的坏块信息BBI(Bad Block Information)表。复制3份是预防系统突然断电,造成BBI表数据丢失。选择最后3个块,主要是出于固件设计。当Flash首次上电,固件程序 通过读取Flash ID,获得设备的容量等信息,然后从Flash的最后一块中寻找BBI表,如果最后一块没有发现BBI表,则认为此块为坏块,继续前移寻找,依此类推,直 到在预留的3个块中找到,并将其数据读入到在主控芯片为其开设的RAM中。如果还找不到,则固件认为该片Flash没有BBI表。交换块区是对NAND Flash进行擦除或写操作时用来临时存放数据,共分配5个块。选取5块是出于可
44、靠性设计。用一个数组 FlashSwapBlockStatusFLASH_SWAP_BLOCKS记录交换块状态:有效还是已经损坏。初始化时,固件认为所有的交换块都 是有效块,在随后对其进行擦除或写操作时,通过读Flash状态寄存器判断该交换块的真实状态,并记录在数组中。交换块的管理围绕固件请求返回当前可用交 换块地址或当前正在使用的交换块地址,并判断标记当前使用的交换块状态为坏。 坏块映射区是当主机向数据区写数据时,检测到当前块(数据区)为坏块时,将数据写到坏块映射区中的相应好块中,并且将这两个块的块地址记录到BBI表 中,以后主机若要对当前块(数据区)访问
45、时,只需读BBI表就可以找到相应映射块,从而代替坏块的访问。这样就使文件系统所见逻辑块地址 LBA(Logical Block Address)变成连续的,但实际上物理块地址PBA(Physical Block Address)可能并不连续。上述方法就是坏块管理的精髓。出于保守设计本文共选50块作为重映块。用数组 FlashRemapBlockStatusFLASH_BAD_BLOCKS_REMAP标识坏块映射区的状态:未使用、已使用还是已经损坏。初始 化时认为坏块映射区中所有块都是好块。3 NFTL坏块管理设计3.1 构建BBI表 用一数组FlashBad
46、BlockTable2FLASH_BAD_BLOCKS_REMAP存放BBI表。第一维为坏块(数据区)的块地址,第二维为映射块地址(重映块)。 BBI表的构建可在Flash首次上电时,通过读取厂商设置在Flash备用区中的坏块标记识别坏块,建立坏块映射表,此法初始化时间与Flash的容 量成正比;或通过读NAND Flash所有块内容并和0xFF作比较3,如果不相同,则表示坏块。这种方法只针对新闪存,并且构建BBI表的时间长,主控芯片的占用率高;另一种 方法是在Flash初次上电时先不建立坏块表,认为当前所有的块都是好块,在随后操作中发现坏块,并更新BBI表
47、。本文选择后一种方法。3.2 坏块映射表区的设计 将BBI表通过特殊的方式保存,以后通过此种方式的逆向来识别BBI表。坏块映射表区的3个块的设计方法如下: (1)在每块最后一页的首字节处做特殊标记,用于标识该块有没有准备被擦除:0xFF表示没有准备被擦除;0x00表示该块已经准备被擦除4。 (2)在每块的倒数第二页的首字节处写0x00,表示该块存放BBI表数据;并在第2、3、4、5个字节处以大端模式存放校验和,用于校验该块中存放的所有数据的正确性。该页的剩余字节写0xFF。 &
48、#160; (3)在第一页起依次写:表头特殊标记(0x0055AAFF)、坏块总数(FlashBadBlockCount)、BBI表(FlashBadBlockTable)、重映块状态(FlashRemapBlockStatus),其结构如图3所示。3.3 逻辑地址映射 在与主机批量数据传输时,首先对主机发送的CBW命令解析,从而固件获得主机请求数据传输的LBA,再对LBA地址映射以此获得相应的PBA,然后再执 行主机命令。具体方法:首先读取当前总的坏块数FlashBadBlocksCount,如果为0,表示无坏块,LBA就不用映射,直接返回;如
49、果最后一 次访问地址与LBA同属于一个块,那么也不用地址映射;如果当前坏块的数量为1,判断LBA块地址与BBI表中坏块地址是否相同,从而决定是否采取地址映 射;如果当前坏块的数量不为1,就需要查找BBI表判断是不是含有LBA的块地址,如果存在,则要地址重新映射,如果不存在,就不用重新映射。可以采用二 分法查表实现两地址快速比较4。3.4 坏块处理 对映射后的地址进行写或擦除过程中发现当前块变坏的处理方法:首先查找映射区中的块状态 FlashRemapBlockStatusFLASH_BAD_BLOCKS_REMAP,寻找可用的映射块。如果50个重映块都被标记
50、为坏或已使 用,则程序进入死循环;如果找到可用的映射块,则固件对可能出现坏块的三种情况进行散转:(1)擦除当前块时出错:将当前块地址与可用的重映块地址写入 BBI表中,按地址大小排列有利于二分法查表,并返回重映块地址。(2)复制某页从交换区到操作地址时失败:首先获得当前使用的交换块的块地址,然后判断 操作地址是在数据存储区还是在重映区。如果在重映区,说明当前操作地址所对应的在数据存储区中的块已经是坏块,并且在这次操作中重映块也变坏,此时就应该 标记当前映射块状态为坏,并在重映区中寻找下一个可用重映块,将原来在数据存储区中的块地址与更新后的映射块地址写入BBI表中,并返回新的映射后的地 址;如果
51、在数据存储区,就进行第一次重映射,更新坏块表,并且将映射地址返回。然后再完成复制工作。(3)向操作地址写一页数据时出错:将当前地址所在块 中的前面页从交换块中相应地址复制到重映块,然后将操作地址所在当前页中的没有写到的数据从交换块中复制,并将缓冲区中的数据重新写到重映射的地址中,并 返回重映射地址。函数实现如下: DWORD FlashDealBadBlock(DWORD Addr,DWORD Type) DWORD i; DWORD
52、RemapBlockAddr; DWORD SwapBlockAddr; while(1) RemapBlockAddr=FlashGetNewRemapBlock(); if(RemapBlockAddr=-1) return Addr; &
53、#160; switch(Type) case 1: goto Exit; break; case 2:
54、0; SwapBlockAddr=FlashGetCurrentSwapBlock(); for(i=0;i<(Addr&(FLASH_BLOCK_SIZE-1)/FLASH_PAGE_SIZE+1;i+) if(0x00=(FlashCopyPage(SwapBlockAddr+i*FLASH_P
55、AGE_SIZE,RemapBlockAddr+i*FLASH_PAGE_SIZE) goto BadRemapBlock; goto Exit; break;
56、160; case 3: SwapBlockAddr=FlashGetCurrentSwapBlock(); for(i=0;i<(Addr&(FLASH_BLOCK_SIZE-1)/FLASH_PAGE_SIZE;i+)
57、160; if(0x00=(FlashCopyPage(SwapBlockAddr+i*FLASH_PAGE_SIZE,RemapBlockAddr+i*FLASH_PAGE_SIZE) goto BadRemapBlock; if(0x00=(FlashCopyPage(Addr,RemapBlo
58、ckAddr+i*FLASH_PAGE_SIZE) goto BadRemapBlock; goto Exit; break; default:
59、;break; BadRemapBlock: FlashMarkRemapBlockBad(RemapBlockAddr); Exit:FlashUpdateBadBlockTable(Addr,RemapBlockAddr); return RemapBlockAddr+(Addr&(FLASH_BLOCK_SIZE-1);3.5 连续读写操作 当主机与设备建立批量传输
60、数据连接时,固件通过解析CBW封包获得起始LBA。对该地址进行映射和坏块管理从而获得PBA。设置一个变量,当此变量有效 时,表示主机对Flash仍需要读或写数据,直到此变量失效为止。同时将主机上一次读写扇区的地址存入另一个变量,此变量在连续读中作用不大,但在连续写 时,通过与上一次写操作地址所在块做比较,判断是否同属一个块,以此决定是不是需要进行地址跨块处理。 本文设计了一种针对NAND型的闪存转译层,使NFTL完成地址映射和坏块管理以及连续读写数据的操作。对NAND Flash的分区设计,使块管理结构清晰,有利于固件的开发。本文没有对Flash的ECC校验进行过多的设计,这是因为在实际应用中NAND Flash主要用于存储多媒体数据(图片、语音文件)等,并不会对它进行频繁的写入或擦除操作,而且多媒体文件数据对数据的完整性不敏感5,所以不需 要对存储在其中的每一位数据进行严格的ECC校验,可以通过另外设计简单的校验方法来代替ECC校验。3、参考ST官方资料计算
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年安庆市大观区事业单位公开招聘工作人员笔试历年典型考题及考点剖析附带答案详解
- 2024-2025公司项目负责人安全培训考试试题及答案综合题
- 2024-2025新员工入职前安全培训考试试题及参考答案(新)
- 2025厂里厂里安全培训考试试题考点精练
- 2025在线教育平台劳动合同模板
- 2025食品销售合同范本
- 2025授权协议国际期货授权协议合同
- 2025中文合作合同范本
- 2025保险公司车辆抵押借款合同范本
- 2025家庭装修设计合同范本
- 煤矿反三违认定培训课件
- 超高清视频技术
- 2024年安全标志标识标准图册
- 浙江省嘉兴市2024-2025学年高一化学下学期期末考试试题含解析
- 2024年山东青岛局属高中自主招生化学试题(含答案)
- 父女断亲协议书范文模板
- 应急管理概论教学课件
- 7《不甘屈辱 奋勇抗争》(教学设计)-2023-2024学年道德与法治五年级下册统编版
- DLT 1053-2017 电能质量技术监督规程
- 机电设备故障诊断与维修 课件 第二章 机械设备故障诊断
- 自投户用光伏合同
评论
0/150
提交评论