在Nand Flash上构建FAT文件系统
Nand Flash文件系统解决方案
Nand Flash文件系统解决方案一.Nand Flash结构及特性NAND Flash的结构如图1所示:图1 NAND Flash结构NAND Flash 由块(block)组成,每块又由若干页(page)组成,每页由数据区和冗余区(spare area)组成。
页是数据写入的基础单元,块是擦除的基础单元。
在对NAND Flash 进行写操作(页编程)时,只能把相应的位由“1”写为“0”,只有对块进行擦除操作时,才能把该块内所有位由“0”写为“1”。
因此,在写入数据时,如果该页内已存有数据,必须先擦除该块。
SLC(Single-Level Cell)小容量的NAND Flash页一般为(512+16)Bytes(数据区512Bytes,冗余区16Bytes),大容量的NAND Flash页为(2048+64)Bytes。
为降低Flash的制造成本,半导体制造商先后推出了MLC(Multi-Level Cell)和TLC(Trinary-Level Cell)技术,即在一个Flash 存储单元内存储更多的位信息,其原理如图2 所示。
与SLC 相比,MLC和TLC 的存储密度更高,成本也相对降低,但管理难度更大:其传输速度、耗电量、擦写次数等方面的性能都要比前者差。
因此在工业应用场合,存储空间要求不是特别大的情况下,SLC仍然得到广泛的应用。
图2 SLC 和TCL区别1. 块擦除次数有限NAND Flash的块擦除次数是有限的。
SLC一般不超过10万次,而MLC擦除次数仅有1万次左右,具体数据以所使用的NAND Flash 的产品手册为准。
如果频繁擦除某块最终导致超过擦除次数限制,该块内的数据将变得不可靠,进而影响整个存储器的使用,所以需要采用损耗均衡算法使各个块近似均衡使用。
2. 异位更新(Non-In-Place Update)由于 NAND Flash先擦后写的物理特性,如果将文件存储在固定的块内,会面临掉电数据丢失及占用较大RAM 等问题。
移植FATFS的NANDFLASH驱动
STM32EWARM开发过程简介之五--移植FATFS的NANDFLASH驱动一,建立工程FATFS源码1,在/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的src文件夹复制到D:\works\EK-STM3210E-UCOSII下,并改名为Fatfs;2,在IDE工程中右击选择“Add Group”建立“FATFS”文件组,并在“FATFS”上右击选择“Add Files”添加D:\works\EK-STM3210E-UCOSII\Fatfs下的C文件;3,把D:\works\EK-STM3210E-UCOSII\Fatfs文件夹目录添加到项目头文件搜索路径中,如:$PROJ_DIR$\..\..\Fatfs二,移植NANDFLASH驱动接口1,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.c复制到D:\works\EK-STM3210E-UCOSII\Drivers下,并加入到工程的DRV文件组;2,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.h复制到D:\works\EK-STM3210E-UCOSII\Include下;3,在fsmc_nand.c前添加上#include"stm32f10x_conf.h",并把系统中的"stm32f10x_conf.h"文件的/*#include"stm32f10x_fsmc.h"*/注释打开;三,修改FATFS的配置文件1,把D:\works\EK-STM3210E-UCOSII\Fatfs下的ff.h中的宏定义:#define_USE_MKFS0#define_CODE_PAGE932#define_FS_RPATH0#define_MAX_SS512修改为:#define_USE_MKFS1#define_CODE_PAGE936#define_MAX_SS2048#define_FS_RPATH12,把D:\works\EK-STM3210E-UCOSII\Fatfs下的integer.h的宏定义:typedef enum{FALSE=0,TRUE}BOOL;修改为:typedef bool BOOL;//typedef enum{FALSE=0,TRUE}BOOL;四,修改FATFS的DISK/IO接口1,把diskio.c复制后改名为nandio.c替换掉工程中的diskio.c,并添加到EWARM的工程中的“FATFS”文件组;2,媒介初始化直接返回正常的0:DSTATUS disk_initialize(BYTE drv){return0;}3,媒介状态查询直接返回正常的0:DSTATUS disk_status(BYTE drv){return0;}4,取系统系统直接返回0(自己可以按格式修改为真实时间):DWORD get_fattime(void){return0;}5,媒介控制接口:DRESULT disk_ioctl(BYTE drv,BYTE ctrl,void*buff){DRESULT res=RES_OK;uint32_t result;if(drv){return RES_PARERR;}switch(ctrl){case CTRL_SYNC:break;case GET_BLOCK_SIZE:*(DWORD*)buff=NAND_BLOCK_SIZE;break;case GET_SECTOR_COUNT:*(DWORD*)buff=(((NAND_MAX_ZONE/2)*NAND_ZONE_SIZE)*NAND_BLOCK_SIZE);break;case GET_SECTOR_SIZE:*(WORD*)buff=NAND_PAGE_SIZE;break;default:res=RES_PARERR;break;}return res;}6,媒介多扇区读接口:DRESULT disk_read(BYTE drv,BYTE*buff,DWORD sector,BYTE count){uint32_t result;if(drv||!count){return RES_PARERR;}result=FSMC_NAND_ReadSmallPage(buff,sector,count);if(result&NAND_READY){return RES_OK;}else{return RES_ERROR;}}7,媒介多扇区写接口:#if_READONLY==0DRESULT disk_write(BYTE drv,const BYTE*buff,DWORD sector,BYTE count) {uint32_t result;uint32_t BackupBlockAddr;uint32_t WriteBlockAddr;uint16_t IndexTmp=0;uint16_t OffsetPage;/*NAND memory write page at block address*/WriteBlockAddr=(sector/NAND_BLOCK_SIZE);/*NAND memory backup block address*/BackupBlockAddr=(WriteBlockAddr+(NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);OffsetPage=sector%NAND_BLOCK_SIZE;if(drv||!count){return RES_PARERR;}/*Erase the NAND backup Block*/result=FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);/*Backup the NAND Write Block to High zone*/for(IndexTmp=0;IndexTmp<NAND_BLOCK_SIZE;IndexTmp++){FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}/*Erase the NAND Write Block*/result=FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);/*return write the block with modify*/for(IndexTmp=0;IndexTmp<NAND_BLOCK_SIZE;IndexTmp++){if((IndexTmp>=OffsetPage)&&(IndexTmp<(OffsetPage+count))){FSMC_NAND_WriteSmallPage((uint8_t*)buff,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,1);buff=(uint8_t*)buff+NAND_PAGE_SIZE;}else{FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}}if(result==NAND_READY){return RES_OK;}else{return RES_ERROR;}}#endif/*_READONLY*/五,调用接口及测试代码1,调用接口,先初始化FSMC和NANDFLASH://NANDFLASH HY27UF081G2A-TPCB#define NAND_HY_MakerID0xAD#define NAND_HY_DeviceID0xF1/*Configure the NAND FLASH*/void NAND_Configuration(void){NAND_IDTypeDef NAND_ID;/*Enable the FSMC Clock*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);/*FSMC Initialization*/FSMC_NAND_Init();/*NAND read ID command*/FSMC_NAND_ReadID(&NAND_ID);/*Verify the NAND ID*/if((NAND_ID.Maker_ID==NAND_ST_MakerID)&&(NAND_ID.Device_ID==NAND_ST_DeviceID)){printf("ST NANDFLASH");}elseif((NAND_ID.Maker_ID==NAND_HY_MakerID)&&(NAND_ID.Device_ID==NAND_HY_DeviceID)) {printf("HY27UF081G2A-TPCB");}printf("ID=0x%x%x%x%x\n\r",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID); }2,然后对媒介格式化,创建读写文件:void test_fatfs(void){FATFS fs;FIL fl;FATFS*pfs;DWORD clust;unsigned int r,w,i;FRESULT res;//NF_CHKDSK(0,1024);display_page(0,0);//for mountres=f_mount(0,&fs);printf("f_mount=%x\n\r",res);//for format//res=f_mkfs(0,1,2048);//MUST Format for New NANDFLASH!!! //printf("f_mkfs=%x\n\r",res);//forpfs=&fs;res=f_getfree("/",&clust,&pfs);printf("f_getfree=%x\n\r",res);printf("\n\r%lu MB total drive space.""\n\r%lu MB available.\n\r",(DWORD)(pfs->max_clust-2)*pfs->csize/2/1024,clust*pfs->csize/2/1024);//for readres=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING|FA_READ);printf("f_open=%x\n\r",res);for(i=0;i<2;i++){for(r=0;r<NAND_PAGE_SIZE;r++){RxBuffer[r]=0xff;}res=f_read(&fl,RxBuffer,NAND_PAGE_SIZE,&r);printf("f_read=%x\n\r",res);if(res||r==0)break;for(r=0;r<NAND_PAGE_SIZE;r++){printf("D[%08x]=%02x",(i*NAND_PAGE_SIZE+r),RxBuffer[r]);if((r%8)==7){printf("\n\r");}}}f_close(&fl);//for writeres=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS|FA_WRITE); printf("f_open=%x\n\r",res);for(i=0;i<2;i++){for(w=0;w<NAND_PAGE_SIZE;w++){TxBuffer[w]=((w<<0)&0xff);}res=f_write(&fl,TxBuffer,NAND_PAGE_SIZE,&w);printf("f_write=%x\n\r",res);if(res||w<NAND_PAGE_SIZE)break;}f_close(&fl);//for umountf_mount(0,NULL);}六,编写NANDFLASH接口1,fsmc_nand.c文件:/*Includes------------------------------------------------------------------*/ #include"fsmc_nand.h"#include"stm32f10x_conf.h"/**@addtogroup StdPeriph_Examples*@{*//**@addtogroup FSMC_NAND*@{*//*Private typedef-----------------------------------------------------------*/ /*Private define------------------------------------------------------------*/#define FSMC_Bank_NAND FSMC_Bank2_NAND#define Bank_NAND_ADDR Bank2_NAND_ADDR#define Bank2_NAND_ADDR((uint32_t)0x70000000)/*Private macro-------------------------------------------------------------*//*Private variables---------------------------------------------------------*//*Private function prototypes-----------------------------------------------*//*Private functions---------------------------------------------------------*//***@brief Configures the FSMC and GPIOs to interface with the NAND memory. *This function must be called before any write/read operation*on the NAND.*@param None*@retval:None*/void FSMC_NAND_Init(void){GPIO_InitTypeDef GPIO_InitStructure;FSMC_NANDInitTypeDef FSMC_NANDInitStructure;FSMC_NAND_PCCARDTimingInitTypeDef p;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);/*--GPIO Configuration------------------------------------------------------*//*CLE,ALE,D0->D3,NOE,NWE and NCE2NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_Init(GPIOD,&GPIO_InitStructure);/*D4->D7NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; GPIO_Init(GPIOE,&GPIO_InitStructure);/*NWAIT NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOD,&GPIO_InitStructure);/*INT2NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_Init(GPIOG,&GPIO_InitStructure);/*--FSMC Configuration------------------------------------------------------*/p.FSMC_SetupTime=0x1;p.FSMC_WaitSetupTime=0x3;p.FSMC_HoldSetupTime=0x2;p.FSMC_HiZSetupTime=0x1;FSMC_NANDInitStructure.FSMC_Bank=FSMC_Bank2_NAND;FSMC_NANDInitStructure.FSMC_Waitfeature=FSMC_Waitfeature_Enable;FSMC_NANDInitStructure.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_8b; FSMC_NANDInitStructure.FSMC_ECC=FSMC_ECC_Enable;FSMC_NANDInitStructure.FSMC_ECCPageSize=FSMC_ECCPageSize_512Bytes; FSMC_NANDInitStructure.FSMC_TCLRSetupTime=0x00;FSMC_NANDInitStructure.FSMC_TARSetupTime=0x00;FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct=&p;FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct=&p;FSMC_NANDInit(&FSMC_NANDInitStructure);/*FSMC NAND Bank Cmd Test*/FSMC_NANDCmd(FSMC_Bank2_NAND,ENABLE);}/***@brief Reads NAND memory's ID.*@param NAND_ID:pointer to a NAND_IDTypeDef structure which will hold *the Manufacturer and Device ID.*@retval:None*/void FSMC_NAND_ReadID(NAND_IDTypeDef*NAND_ID){uint32_t data=0;/*Send Command to the command area*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READID; /*Send Address to the address area*/*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=NAND_CMD_IDADDR;/*Sequence to read ID from NAND flash*/data=*(__IO uint32_t*)(Bank_NAND_ADDR|DATA_AREA);NAND_ID->Maker_ID=DATA_1st_CYCLE(data);NAND_ID->Device_ID=DATA_2nd_CYCLE(data);NAND_ID->Third_ID=DATA_3rd_CYCLE(data);NAND_ID->Fourth_ID=DATA_4th_CYCLE(data);}/***@brief This routine is for move one2048Bytes Page size to an other2048Bytes Page.*the copy-back program is permitted just between odd address pages or even address pages. *@param SourcePageAddress:Source page address*@param TargetPageAddress:Target page address*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress,uint32_t TargetPageAddress) {uint32_t status=NAND_READY;uint32_t data=0xff;/*Page write command and address*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE2;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE3;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Check status for successful operation*/status=FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;return(status);}/***@brief This routine is for writing one or several2048Bytes Page size.*@param pBuffer:pointer on the Buffer containing data to be written*@param PageAddress:First page address*@param NumPageToWrite:Number of page to write*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_WriteSmallPage(uint8_t*pBuffer,uint32_t PageAddress,uint32_t NumPageToWrite){uint32_t index=0x00,numpagewritten=0x00,addressstatus=NAND_VALID_ADDRESS;uint32_t status=NAND_READY,size=0x00;uint32_t data=0xff;while((NumPageToWrite!=0x00)&&(addressstatus==NAND_VALID_ADDRESS)&&(status==NAND_READY)) {/*Page write command and address*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_WRITE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);/*Calculate the size*/size=NAND_PAGE_SIZE+(NAND_PAGE_SIZE*numpagewritten);/*Write data*/for(;index<size;index++){*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA)=pBuffer[index];}*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_WRITE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Check status for successful operation*/status=FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;if(status==NAND_READY){numpagewritten++;NumPageToWrite--;/*Calculate Next small page Address*/if(PageAddress++>(NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) {addressstatus=NAND_INVALID_ADDRESS;}}}return(status|addressstatus);}/***@brief This routine is for sequential read from one or several*2048Bytes Page size.*@param pBuffer:pointer on the Buffer to fill*@param PageAddress:First page address*@param NumPageToRead:Number of page to read*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_ReadSmallPage(uint8_t*pBuffer,uint32_t PageAddress,uint32_t NumPageToRead) {uint32_t index=0x00,numpageread=0x00,addressstatus=NAND_VALID_ADDRESS;uint32_t status=NAND_READY,size=0x00;*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READ1;while((NumPageToRead!=0x0)&&(addressstatus==NAND_VALID_ADDRESS)){/*Page Read command and page address*/*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READ2;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Calculate the size*/size=NAND_PAGE_SIZE+(NAND_PAGE_SIZE*numpageread);/*Get Data into Buffer*/for(;index<size;index++){pBuffer[index]=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);}numpageread++;NumPageToRead--;/*Calculate page address*/if(PageAddress++>(NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) {addressstatus=NAND_INVALID_ADDRESS;}}status=FSMC_NAND_GetStatus();return(status|addressstatus);}/***@brief This routine erase complete block from NAND FLASH*@param PageAddress:Any address into block to be erased*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*/uint32_t FSMC_NAND_EraseBlock(uint32_t PageAddress){uint32_t data=0xff,status=NAND_ERROR;*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_ERASE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_ERASE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Read status operation------------------------------------*/FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;return(status);}/***@brief This routine reset the NAND FLASH*@param None*@retval:NAND_READY*/uint32_t FSMC_NAND_Reset(void){*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_RESET;return(NAND_READY);}/***@brief Get the NAND operation status*@param None*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate *a Timeout error*-NAND_READY:when memory is ready for the next operation*/uint32_t FSMC_NAND_GetStatus(void){uint32_t timeout=0x1000000,status=NAND_READY;status=FSMC_NAND_ReadStatus();/*Wait for a NAND operation to complete or a TIMEOUT to occur*/ while((status!=NAND_READY)&&(timeout!=0x00)){status=FSMC_NAND_ReadStatus();timeout--;}if(timeout==0x00){status=NAND_TIMEOUT_ERROR;}/*Return the operation status*/return(status);}/***@brief Reads the NAND memory status using the Read status command *@param None*@retval:The status of the NAND memory.This parameter can be:*-NAND_BUSY:when memory is busy*-NAND_READY:when memory is ready for the next operation *-NAND_ERROR:when the previous operation gererates error*/uint32_t FSMC_NAND_ReadStatus(void){uint32_t data=0x00,status=NAND_BUSY;/*Read status operation------------------------------------*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_STATUS; data=*(__IO uint8_t*)(Bank_NAND_ADDR);if((data&NAND_ERROR)==NAND_ERROR){status=NAND_ERROR;}else if((data&NAND_READY)==NAND_READY){status=NAND_READY;}else{status=NAND_BUSY;}return(status);}2,fsmc_nand.h文件:/*Define to prevent recursive inclusion-------------------------------------*/ #ifndef__FSMC_NAND_H#define__FSMC_NAND_H/*Includes------------------------------------------------------------------*/ #include"stm32f10x.h"/*Exported types------------------------------------------------------------*/ typedef struct{uint8_t Maker_ID;uint8_t Device_ID;uint8_t Third_ID;uint8_t Fourth_ID;}NAND_IDTypeDef;typedef struct{uint16_t Zone;uint16_t Block;uint16_t Page;}NAND_ADDRESS;/*Exported constants--------------------------------------------------------*/ /*NAND Area definition for STM3210E-EVAL Board RevD*/#define CMD_AREA(uint32_t)(1<<16)/*A16=CLE high*/ #define ADDR_AREA(uint32_t)(1<<17)/*A17=ALE high*/#define DATA_AREA((uint32_t)0x00000000)/*FSMC NAND memory command*/#define NAND_CMD_READ1((uint8_t)0x00)#define NAND_CMD_READ2((uint8_t)0x30)#define NAND_CMD_WRITE0((uint8_t)0x80)#define NAND_CMD_WRITE1((uint8_t)0x10)#define NAND_CMD_MOVE0((uint8_t)0x00)#define NAND_CMD_MOVE1((uint8_t)0x35)#define NAND_CMD_MOVE2((uint8_t)0x85)#define NAND_CMD_MOVE3((uint8_t)0x10)#define NAND_CMD_ERASE0((uint8_t)0x60)#define NAND_CMD_ERASE1((uint8_t)0xD0)#define NAND_CMD_READID((uint8_t)0x90)#define NAND_CMD_IDADDR((uint8_t)0x00)#define NAND_CMD_STATUS((uint8_t)0x70)#define NAND_CMD_RESET((uint8_t)0xFF)/*NAND memory status*/#define NAND_VALID_ADDRESS((uint32_t)0x00000100)#define NAND_INVALID_ADDRESS((uint32_t)0x00000200)#define NAND_TIMEOUT_ERROR((uint32_t)0x00000400)#define NAND_BUSY((uint32_t)0x00000000)#define NAND_ERROR((uint32_t)0x00000001)#define NAND_READY((uint32_t)0x00000040)/*FSMC NAND memory parameters*///#define NAND_PAGE_SIZE((uint16_t)0x0200)/*512bytes per page w/o Spare Area*/ //#define NAND_BLOCK_SIZE((uint16_t)0x0020)/*32x512bytes pages per block*///#define NAND_ZONE_SIZE((uint16_t)0x0400)/*1024Block per zone*///#define NAND_SPARE_AREA_SIZE((uint16_t)0x0010)/*last16bytes as spare area*///#define NAND_MAX_ZONE((uint16_t)0x0004)/*4zones of1024block*//*FSMC NAND memory HY27UF081G2A-TPCB parameters*/#define NAND_PAGE_SIZE((uint16_t)0x0800)/*2048bytes per page w/o Spare Area*/ #define NAND_BLOCK_SIZE((uint16_t)0x0040)/*64x2048bytes pages per block*/#define NAND_ZONE_SIZE((uint16_t)0x0200)/*512Block per zone*/#define NAND_SPARE_AREA_SIZE((uint16_t)0x0040)/*last64bytes as spare area*/#define NAND_MAX_ZONE((uint16_t)0x0002)/*2zones of1024block*//*FSMC NAND memory data computation*/#define DATA_1st_CYCLE(DATA)(uint8_t)((DATA)&0xFF)/*1st data cycle*/#define DATA_2nd_CYCLE(DATA)(uint8_t)(((DATA)&0xFF00)>>8)/*2nd data cycle*/#define DATA_3rd_CYCLE(DATA)(uint8_t)(((DATA)&0xFF0000)>>16)/*3rd data cycle*/#define DATA_4th_CYCLE(DATA)(uint8_t)(((DATA)&0xFF000000)>>24)/*4th data cycle*//*FSMC NAND memory HY27UF081G2A-TPCB address computation*/#define ADDR_1st_CYCLE(PADDR)(uint8_t)(0x0)/*1st addressing cycle*/#define ADDR_2nd_CYCLE(PADDR)(uint8_t)(0x0)/*2nd addressing cycle*/#define ADDR_3rd_CYCLE(PADDR)(uint8_t)(PADDR&0xFF)/*3rd addressing cycle*/#define ADDR_4th_CYCLE(PADDR)(uint8_t)((PADDR>>8)&0xFF)/*4th addressing cycle*//*Exported macro------------------------------------------------------------*//*Exported functions-------------------------------------------------------*/void FSMC_NAND_Init(void);void FSMC_NAND_ReadID(NAND_IDTypeDef*NAND_ID);uint32_t FSMC_NAND_WriteSmallPage(uint8_t*pBuffer,uint32_t Address,uint32_t NumPageToWrite); uint32_t FSMC_NAND_ReadSmallPage(uint8_t*pBuffer,uint32_t Address,uint32_t NumPageToRead);uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress,uint32_t TargetPageAddress);//uint32_t FSMC_NAND_WriteSpareArea(uint8_t*pBuffer,NAND_ADDRESS Address,uint32_t NumSpareAreaTowrite); //uint32_t FSMC_NAND_ReadSpareArea(uint8_t*pBuffer,NAND_ADDRESS Address,uint32_t NumSpareAreaToRead); uint32_t FSMC_NAND_EraseBlock(uint32_t Address);uint32_t FSMC_NAND_Reset(void);uint32_t FSMC_NAND_GetStatus(void);uint32_t FSMC_NAND_ReadStatus(void);//uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS*Address);#endif/*__FSMC_NAND_H*/七,NFTL代码层有关NFTL代码,自行处理。
基于NOR FLASH的嵌入式FAT文件系统
基于NOR FLASH的嵌入式FAT文件系统张鹏;孙甲松;陈从华【摘要】The paper is to design a feasible solutions that apply the FAT file system concept applied to nor FLASH chip,using BIM(Block Information Map) and MAT(Map Allocation Table).Base on the characteristics of nor flash,the BIM record the state and erasing times of data block without flashing frequently.The MAT locates all system information table in the FLASH.The FAT table and the block information can be written to the FLASH memory in real time.Base on the plan,the design provides reasonable mechanisms of loss-balance,bad-block-management and garbage-collection.The design is suitable for these devices which have limited memory,harsh time of power up,or astable power.The terminal can use the standard interface to store and access the large capacity data quickly.It improve the service of FLASH.%本课题就是要设计一套确实可行的方案,将FAT文件系统管理文件/数据的理念应用于FLASH芯片上.本设计采用了数据块使用情况信息表BIM和定位表MAT这两个结构.通过利用NOR FLASH的特性,在不频繁擦写的情况下记录数据块当前状态和擦写次数,将FAT袁和数据块磨损信息实时写入到FLASH存储器中.在此基础上制定合理的均衡损耗策略,并实现坏块管理、碎片回收.适用于内存资源有限、对上电时间有要求、可能随时掉电的终端.令终端能够使用标准接口快速存储、访问大容量数据,并提高FLASH器件使用寿命.【期刊名称】《电子设计工程》【年(卷),期】2017(025)023【总页数】5页(P159-162,168)【关键词】文件系统;FLASH;FAT;嵌入式【作者】张鹏;孙甲松;陈从华【作者单位】清华大学电子工程系,北京100084;厦门雅迅网络股份有限公司福建厦门361008;清华大学电子工程系,北京100084;厦门雅迅网络股份有限公司福建厦门361008【正文语种】中文【中图分类】TN302FLASH即半导体存储器,已被广泛应用于便携式设备等嵌入式系统中。
NAND Flash驱动程序结构
NAND Flash驱动程序1、NAND Flash驱动程序框架FAT文件系统下的NAND Flash驱动程序采用了分层结构。
驱动程序的上层是Flash抽象层,是物理操作无关层,该层对NAND Flash的操作进行抽象,并采用一定的策略平衡了NAND Flash的擦写。
NAND Flash驱动程序的结构如图5.5所示。
图5.5 FAT下NAND Flash驱动结构在图中:File System即文件系统。
在这里,采用的是FAT文件系统。
FAT文件系统是一种采用链式分配方式的文件系统。
并没有对NAND Flash的特点优化,因此需要在下层的驱动程序做优化。
Flash Driver即NAND Flash驱动程序。
对上层的文件系统提供以DSK为前缀的流驱动接口。
该层驱动程序本身分为两层:FAL层、F MD层。
(1)、FAL层即Flash Abstraction Layer,Flash抽象层。
该层主要提供三个功能:A、将物理的Flash抽象成统一的接口提供给上层的文件系统。
B、将逻辑扇区地址转换成物理扇区地址。
上层的FAT文件系统使用的是逻辑扇区地址,并不是真正的物理扇区,其转换由FAL实现。
C、对Flash实现损耗平衡("Wear-level")。
为了避免反复的擦写Flash的同一个块,需要一种策略来减少反复的擦写块。
(2)、FMD层即Flash Media Driver,Flash介质驱动层。
该层实现FAL层的请求,对Flash物理扇区进行操作。
Flash Hardware即NAND Flash物理芯片。
2、FAL层(Flash Abstraction Layer)1)函数接口定义FAL层对上的函数接口也就是整个NAND Flash驱动程序的对外接口,由于NAND Flash 是块设备,Windows CE中块设备采用的是流驱动接口,流驱动接口是一个标准的统一接口,只是各个驱动的前缀不同,在这里NAND Flash函数接口的前缀为“DSK”,这个前缀也使得Windows CE将“DSKxx:”的文件名看作为设备,使得我们能够通过Windows CE标准的Win32 API,如CreateFile、DeviceIOControl等来对设备进行打开、读写等操作。
NandFlash建tffs文件系统问题小结
Nand Flash k9f2808u0c建立tffs文件系统问题小结Searcher caiyang一.环境介绍目的:在nand flash k9f2808u0c上建立tffs文件系统硬件环境:44B0, bank0 接2M nor flash,bank1接16M nand flash k9f2808U0c二.进展程度1. bootRom编译无误,通过在启动到cmdLoop中加入’Z’调用tffsDevFormat()函数,实现tffs的格式化。
2. bootRom编译无误,通过在启动到cmdLoop中加入’Y’调用sysTffsFormat()函数,实现tffs的代参格式化。
3. bootRom编译无误,通过在启动到cmdLoop中加入’X’调用usrTffsConfig()函数,实现tffs的挂接。
4. 通过验证,单独的读,写,擦除函数均可正确执行,而在进行tffs文件系统的建立,综合调用这几个函数时,出现错误。
调用顺序xxIdentify()->xxErase()->xxRead()->xxWrite()。
三.问题小结1. 调试输出信息不一致问题问题描述:通过加载vxWorks调试tffs文件系统与通过bootrom调试输出信息不一致,详细描述如下:1)通过网络加载包含tffs信息的vxWorks启动加载后,在shell中调用tffsDevFormat输出相应的格式化信息2)烧写bootrom.hex到flash中启动后,回车输入'Z'(在bootconfig.c,调用了tffsDevFormat())后,出现相应的打印信息问题:二者输出的信息(调用tffsDevFormat()后的打印信息)不一致:其中bootrom.hex和vxWorks是在同一个工程中编译生成的。
2. nandMap()函数的调用关系问题问题描述:在调用tffsDevFormat()函数进行格式化擦除过程中,调用eraseBlock 操作顺利完成后进入nandMap() 函数。
在NAND FLASH上建立TFFS文件系统小结
在NAND FLASH上建立TFFS文件系统小结by minuetfrom EDW经过一个星期的摸索,终于在NAND FLASH上建立了TFFS文件系统,今天拿出来和大家分享一下!相信大家对NAND FLASH的特点和与NOR FLASH的区别都有所了解,有关这方面的文章坛子里有,我就不在赘述了。
下面我以三星的K9F6408U0C为例(它是8M x 8 Bit NAND Flash Memory),详细说明建立过程。
环境:tornado2.0 for arm一、硬件连接主要是CLE和ALE的连接,可以用I/O口控制,也可以直接与地址线相连。
我选择后者,因为这种方*既方便,访问速度也比I/O口控制快。
我是让CLE接在A20上,ALE接在A21上。
还要注意/WP(写保护)这个脚,使其上拉。
我在工作过程中曾忽略了对它的控制(浮空),导致写保护有效,擦写都无效。
希望大家不要犯同样的错误。
/CE这个脚我是接在CPU的BANK1片选上,即界于0x1000000~0x1ffffff的16M地址都是指向此flash设备,当然我们只要选择一个地址表示即可,简单起见选0x1000000。
R//B接在CPU的一个输入I/O上,通过读此I/O判断设备是忙还是准备好。
有的片子要求在片子忙状态时,/CE要是低电平,所以建议R//B与/CE连接在一起。
综上所述,可以如此定义:#define WRITE_COMMAND(val) (*(volatile char *)0x1100000 = (char)(val)) /* CLE = A20 */#define WRITE_ADDRESS(val) (*(volatile char *)0x1200000 = (char)(val)) /* ALE = A21 */#define WRITE_DATA(val) (*(volatile char *)0x1000000 = (char)(val)) /* CE = 0 CLE = 0 ALE = 0 */#define READ_DATA(val) ((char)(val) = *(volatile char *)0x1000000) /* CE = 0 CLE = 0 ALE = 0 */#define READ_REG(val) ((int)(val) = *(volatile int *)0x60061C) /* PI3寄存器地址*/上班时间到了,先写到这。
FAT文件系统在NANDFlash存储器上的改进设计
paper @ (投稿专用) 2006年第11期Microcontrollers &Embedded Systems 27 F A T文件系统在N A N D F l a s h存储器上的改进设计※■北京交通大学 阎航 摘 要嵌入式系统的大量数据都存储在其Flash 芯片上。
根据Flash 器件的固有特性,构建一个适合管理NAND Flash 存储器的FA T 文件系统,并阐述具体的设计思想。
该系统改进了FA T 表和FR T 表的存储方式,延长了存储器的使用寿命,提高了稳定性。
关键词NAND Flash 存储器 FA T16文件系统 FA T 表 FRT 表 NAND Flash 存储器是一种数据正确性非理想的器件,容易出现位反转现象,同时在使用中可能会有坏损单元。
数据写入必须在空白的区块或者擦除后的区块中进行,其底层技术要求以块为单位进行擦除(将“0xff ”写入到要擦除的存储块中),再按页写入。
Flash 存储器的擦除次数是有限的,一般是1000000次。
当某块执行过度的擦除操作后,这一块的存储空间将会变为“只读”状态,不能再写入数据。
根据以上特点,为了避免某些块的过度操作,而导致存储卡使用寿命降低,设计专门针对Flash 存储器的文件系统是必要的[1]。
1 NAND Flash 存储器的特点NAND Flash 存储器的读取操作与普通SRAM 存储器类似,可以随机读取,读出的速度也很快。
芯片生产厂商规定存储空间的第1块必须是有效块,装载了出厂标识、系统配置等信息;而其他块可能在使用前就是坏块,需要在初次使用时进行坏块检测并标记,禁止数据写入。
由于存储器每一块的内部结构都是相互独立的,坏块并不影响系统的操作[2]。
在设计NAND Flash 文件系统前,首先要了解其内部结构。
目前市面上的NAND Flash 芯片单片容量已高达1G B ,存储器容量最高达4G B (由4片1G B 的芯片封装而成)。
基于NAND FLASH的FAT16文件系统
基于NAND FLASH的FAT16文件系统
赵挺竹
【期刊名称】《电子元器件应用》
【年(卷),期】2009(11)9
【摘要】在分析了NAND FLASH本身特性的基础上,给出了利用缓存机制来适应NANDFLASH先擦后写、分块写入的特性,并运用虚拟内存思想来处理NAND FLASH本身的坏块,从而对FAT16文件系统进行修改,以使其适用于嵌入式环境下的NAND FLASH的具体方法.
【总页数】4页(P92-95)
【作者】赵挺竹
【作者单位】西安电子科技大学
【正文语种】中文
【相关文献】
1.基于Nand Flash的嵌入式Linux文件系统设计 [J], 唐玮;任世琦;郭彦涛
2.基于NAND Flash的文件系统设计与实现 [J], 牛伟;张延园
3.基于NandFLASH高可靠自恢复实时文件系统 [J], 张少波;徐广辉;田小锋;赵峰荣
4.基于NAND-Flash的FAT16文件系统的实现 [J], 刘振纲;庞晓玲
5.一种基于NAND FLASH的FAT文件系统的研究与实现 [J], 张小进;罗海波因版权原因,仅展示原文概要,查看原文内容请购买。
Flash文件系统及存储管理技术研究与实现
1
华 中 科 技 大 学 硕 士 学 位 论 文
性。如果通过灵活的校验机制与坏块管理,则可以达到更高效的存储空间利用率,这对 成本敏感的嵌入式系统来说是更加需要考虑的。 便携式消费电子设备对 Flash 存储器的需求与日俱增, 产品的更新换代以及 Flash 自 身容量的增长速度都越来越快。对于最终产品的开发人员来说,他们希望在采用新类型 的 Flash 存储器时不需要更新产品设计方案、控制器和接口等,以便更快地推出规格升 级的产品。所以,Flash 文件系统和存储管理技术的设计思路和相关算法,对缩短上层 应用开发周期,提高存储可靠性,延长 Flash 存储器的使用寿命等有很大意义。
Keywords: NAND Flash, Flash File System, Flash Translation Layer, Wear-leveling
II
பைடு நூலகம்
独创性声明
本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的 研究成果。尽我所知,除文中已经标明引用的内容外,本论文不包含任何其他个人 或集体已经发表或撰写过的研究成果。对本文的研究做出贡献的个人和集体,均已 在文中以明确方式标明。本人完全意识到本声明的法律结果由本人承担。
关键词: NAND Flash Flash 文件系统
闪存转换层
损耗均衡
I
华 中 科 技 大 学 硕 士 学 位 论 文 Abstract
Nowadays, f lash memory is prevailing in many mobile devices such as MP3 players, flash memory cards, cell phones and PDAs due to its non- volatility, solid-state reliability, small and lightweight package, low-power consumption, etc. Common file systems can not be directly applied to flash memory, so the Flash Translation Layer (FTL) should be designed to allow file system to read and write to flash memory device in the same way as disk drive. Aiming at the widely used NAND flash memory, a FTL is designed and implemented, so the FAT file system is created on NAND flash. Specially, the NAND flash memory storage management issues are deeply researched, including address mapping, wear- leveling algorithm, garbage collection policy, power-off recovery, bad block management, and so on. As well as much more emphases are taken on the problem of identifying user and data security, encrypted-storage mecha nism is designed and implemented. Additionally, this paper proposes layered software architecture of flash memory storage management and intends to research and develop a software module for NAND Flash memory, which is obtained application in the actual product. The following achievements are made in this dissertation: (1) The architecture of flash file system and its implementation form are deeply researched. (2) A NFTL mapping scheme is designed and deeply analyzed for large capacity NAND Flash. (3) Wear-leveling algorithm and garbage collection policy are researched for better system performance and longer flash memory lifespan. (4) Power-off recovery mechanism and bad block management are designed for system higher reliability. (5) Research and impleme ntation of flash memory s torage encryption, including user identification and data encryption.
基于NANDFlash的FAT文件系统的实现
2 修改时间
2 修改日期
2 第一簇地址低 2 Byte
4 文件大小
在磁盘中创建文件或目录时 ,需要在 FAT 表的
指定位置写入以上 32 字节内容 ,这样系统才能确定 文件的存在 。 2. 3 文件存储原理
文件内容具体的存放位置是由 FAT 表中的簇 号列表来确定的 。文件在磁盘中所占用的空间 ,最 小的单位是簇而不是字节 ,即使文件只有一个字节 , 系统也会给它分配一个单元 ,即一簇 。为了可以把 磁盘空间有效地分配给每个文件 ,而且能够准确地 读出文件的内容 ,系统把磁盘空间分成簇来进行管 理 。当存储较大的文件时 ,需要把文件存放到许多 个簇 。同一个文件存放的不一定是连续的簇 ,往往 会分成若干段 ,象链子一样存放 。具体存储方式如 表 3 所示 。
文件系统进行数据的存储就是根据以上所列的
参数来查找存放数据的确切位置的 ,因此这些参数
是否正确是非常重要的 。
2. 2 FAT 目录项结构
FAT 目录项结构 ,包括目录和文件属性的描述 ,
实际上是一个 32 字节的线性表 ,根目录是一个特殊
的目录 ,对于 FAT12/ 16 ,它存储于磁盘固定的位置 ,
3 在 K9F1208 中实现 FAT
要在 Flash 中建立 FAT 文件系统 ,需要按照 FAT 的定义确定好文件头 、FAT 表项以及文件数据的位 置 ,调用 Flash 的操作命令把数据写到相应的位置 , 然后就可以象在 Windows 中访问文件一样对单片机 系统的数据进行访问 。 3. 1 初始化文件系统
创建 FAT 文件系统需要用到对 Flash 的读写操 作。
收稿日期 :2006 - 12 - 20 作者简介 :杨瑞霞(1974 - ) ,女 ,河北省吴桥市人 ,山东政法学院司法信息系讲师 ,硕士 ,主要研究方向 :电子技术与嵌入式系统.
FAT文件系统在NAND FLASH上的改进
可分为: 保留扇区、 文件分配表区和数据 区三部分/ /
图1 。 …
旦旦I 曼
保 留扇 区
文件分配表 , 这就使得对文件分配表区的擦写明显多 于其它区域 , 从而导致文件分配表区先于其它区域 出 现坏块。二是申请新簇时 , 文件系统总是按照从前到 后的秩序查找 F T表 , A 这就使得簇号小的较大的更 频繁地被使用, 从而导致簇号较小的簇更早磨损, 出 现 坏块 。
一
值为 5 0 即当 C U T的值大于 50时 , 0, ON 0 申请 x个簇
2 F T文件 系统存在 的问题及 改进 A
收稿 日期 :0 1 10 21- - 0 8
作者简介 : 牛炳麟 (91)女 , 18. , 河南信 阳人 , 助教
1 26 ・
・
牛炳麟 :A F T文件 系统在 N N L S A D F A H上 的改进
并将 F T表复制到新 申请的簇链 中, A 其中 , 11/ ( , 5 表示簇 2~ 10 X= 05 1 1 ) 簇 30的簇 域共擦 写 了 1 5万 8表示大小为 1 1 , 05个扇 区的 F T表需要 1 1/ 个 次 ) A 058 。 簇来容纳。 3 j 二是记录各簇擦除次数 。在数据 区开辟 Y个簇 2, 0 大小 的区域用以记录所有簇 的擦 除次数。记 录方式 戛 5 S2 为: 在记录区, 1 字节记录数据区一个簇 的擦除次 囊 Q 每 6 1 5 i 0 数, 共需 (29 8 串1 19 1一 Y) 6字节 , Y个簇包含 Y, 0 6 l 9 c 4 字节 , 由等式 ( 298Y), 6=Y% 06可得 Y 则 19 1- l : 1 49 0 =0, 56 即记 录区 大小 为 56簇 。 0 蓑 当申请新簇 时, 申请 到的簇在记 录区的对应 若 图 3 两个文件系统的擦 写均衡性比较 1 字节 的各 位都为 0 则 表示该簇 已经擦写 满 18 32 改进 的文 件 系统 对读 写速 度 的影响 6 , 2 . 次。为了对数据区个簇均衡使用 , 继续往后遍历 F T A 改进后 的 F T 2 A 3 文件系统较标准的 F T 2文件 A3 表, 直至找 到下一 个空 闲簇 , 其擦写 次数 不大 于 系统多了一些额外的处理 , 且 会对 N N L S A DF H的读 A 18 2 次。若不能找到这样 的簇 , 则擦除记 录区, 使所 写速度 产生 影 响 , 从将 上述 的实 验在读 写速 度方 面进 有的 1 字节记录都恢复到初始状态 , 6 这个过程称为 行 跟踪 记 / 4 图 5可 以看 出 , 对 写 速 度 的影 图 , 其 “ 回收” 。待执行回收过程完成后重新 申请新簇 。 响是巨大的, 这是 由于写操 作中增加 了查找记录区、 由于 申请 新簇 过程 新增 了查 找 记 录 区和检 查 1 6 记录擦除次数等处理的缘故 , 而读 的速度几乎没有受 字节各位的操作 , 了提高时效性 , 为 定义一个位图数 到影 响 J 。 组A RS E , R [ I ]数组 的每一位按顺 序和数据 区的簇 Z 对应 , 且每一位都初始化为 1 。其数组大小 S E I Z (29 8 0 )8 19 1- 6 / 。若数据区某簇的擦写满 18 , 5 2次 则置位 图数组对应位为 0 。当执行回收过程时, 重置 数组的各位为初始值 1/ 2 /图 。
NANDFlash文件系统方案及其可靠性设计
随着嵌入式系统在消费电子,数据采集和工业控制等领域得到越来越广泛的应用。
各个领域都对嵌入式系统提出了更高的要求。
作为嵌入式系统中最重要的组成部分,存储系统呈现出了较快的发展速度。
NANDFLASH作为一种安全、快速的存储体,具有体积小、容量大、成本低、以及更多的擦除次数等一系列优点,已成为嵌入式系统中数据和程序最主要的载体。
由于NANDFLASH在结构和操作方式上与硬盘、E2ROM等其他存储介质有较大区别,使用NANDFLASH时必须根据其自身特性,对文件系统进行特殊设计,以保证系统的性能达到最优。
同时由于工艺和使用环境的问题,NANDFlash存储器中不可避免的会出现坏块,因此必须提出有效的坏块处理方法,以解决坏块问题,实现存储系统的高可靠性。
1NANDFLASH特点1.1区块结构NANDFlash存储器内部分为若干个存储单元块(block),每个存储单元块又分为若干个页(page),存储单元块是最小的擦除单位,页是写入数据的最小单位。
1.2先擦后写由于FLASH的写操作只能将数据位从1写成0,不能从0写成1,所以在对存储器进行写入之前必须先执行擦操作,将预写入的数据位初始化为1。
擦操作的最小单位是一个区块,而不是单个字节。
1.3操作指令NANDFLASH的操作不能像RAM那样,直接对目标地址进行总线操作。
比如执行一次写操作,它必须完成一段时序才能将数据写入到FLASH中。
1.4坏块NANDFLASH的坏块是随机分布的,可能在出厂时就存在坏块,也可能在使用过程中,导致某些区块的损坏。
区块一旦损坏,将无法进行修复。
如果对已损坏的区块进行操作,可能会带来不可预测的错误。
2NANDFlash文件系统的设计将整个文件系统分为两个层次,第一层,直接和物理硬件接触,管理Flash物理存储器,第二层,在基层之上,实现文件管理,如实现FAT。
2.1第一层2.1.1物理地址到逻辑地址的映射为了在NANDFlash物理地址和FAT操作的逻辑地址之间建立一个好的映射关系,须对NANDFlash的存储空间在逻辑上进行了重新定义。
面向Flash存储器的FAT文件系统可靠性增强机制
WA N G D o n g , Y A N G Q i o n g , Y A N G J i n g - y u a n
( X i a n A e r o n a u t i c s C o m p u t i n g T e c h n i q u e R e s e a r c h I n s t i t u t e , A V I C , X i a n 7 1 0 0 6 8 , C h i n a )
第4 7卷
第 3期
航 空 计 算 技 术
Ae r o na ut i c a l Co mp u t i ng Te ch n i q u e
Vo 1 . 4 7 No . 3
Ma v . 201 7
2 0 1 7年 5月
面向 F l a s h存 储 器 的 F A T文件 系统 可 靠 性增 强 机 制
Ab s t r a c t : Wh e n F AT il f e s y s t e m i s u s e d f o r la f s h me mo r y, t h e s t o r a g e l o c a t i o n o f il f e a l l o c a t i o n t a b l e i s u n c e r t a i n. a n d t h e e r a s e c o u n t b e t we e n c l u s t e r s i S i mb a l a n c e, a U t h e s e r e s u l t i n t h e d e c r e a s e o f r e l i a bi l i t y . Fo r t h e s e p r o b l e ms, t hi s p a p e r p r o p o s e s t wo s o l ut i o n, t h e y a r e c o n t r o l l a b l e mi g r a t i o n o f il f e ll a o c a t i o n t a b l e a n d we a r l e v e l i ng b e t we e n c l u s t e r s . Th e f 0 i T n e r r e s e r v e s a n u mb e r o f b l o c k s i n la f s h t o s t o r e il f e ll a o c a t i o n t a b l e, wh e n u p d a t i n g il f e a l l o c a t i o n t a bl e, i t s e l e c t s t he b l o c k wh o s e e r a s e c o u nt i s mi n i mu m i n a l l r e — s e ve r d b l o c k s . I t a l s o r e s e r v e s a b l o c k i n la f s h t o r e c o r d e n t r a n c e a d d r e s s o f t h e n e we s t il f e a l l o c a t i o n t a — b l e . Th e l a t t e r r e s e ve r s a b l o c k i n la f s h t o r e c o r d e r a s e c o u n t o f e a c h c l u s t e r, wh e n a l l o c a t i n g s p a c e, i t s e . 1 e c t s t he f r e e c l u s t e r wh o s e e r a s e c o u n t i S l e s s t h a n e r a s e t h r e s h o l d. Ac c o r d i n g t o t e s t r e s u l t . t h e i mp r o v e d
FAT文件系统在NAND Flash存储器上的改进设计
FAT文件系统在NAND Flash存储器上的改进设计
阎航
【期刊名称】《单片机与嵌入式系统应用》
【年(卷),期】2006(000)011
【摘要】嵌入式系统的大量数据都存储在其Flash芯片上.根据Flash器件的固有特性,构建一个适合管理NAND Flash存储器的FAT文件系统,并阐述具体的设计思想.该系统改进了FAT表和FRT表的存储方式,延长了存储器的使用寿命,提高了稳定性.
【总页数】3页(P27-29)
【作者】阎航
【作者单位】北京交通大学
【正文语种】中文
【中图分类】TP3
【相关文献】
1.FAT文件系统在NAND FLASH上的改进 [J], 牛炳麟
2.一种适用于NAND型Flash存储器译码故障检测的改进对角线算法 [J], 刘远飞;李鹏程;刘海涛
3.嵌入式系统大容量NAND Flash存储器分区管理设计 [J], 李远哲;贺海文;万丽;李妍;赵峰
4.FAT文件系统在NAND FLASH上的磨损均衡研究 [J], 谢琦;胡俊;王磊
5.提高FAT文件系统在NAND存储器上可靠性的研究 [J], 姚堃;张俊涛
因版权原因,仅展示原文概要,查看原文内容请购买。
FAT文件系统在NAND Flash存储器上的改进设计
NA D Fah存 储 器 是 一 种 数 据 正 确 性 非 理 想 的 器 N ls 件 , 易 出 现 位 反 转 现 象 , J 在 使 用 中 可 能 会 有 坏 损 单 容 I时 —
元 。数 据 写 入 必 须 在 空 白 的 区 块 或 者 擦 除 后 的 区 块 中 进
81 2 lG +3 。存 储 器 每 页 带 有 6 9 一 B 2MB 4字 节 的 冗 余
要 在 初 次 使 用 时 进 行 坏 块 检 测 并 标 记 , 止 数 据 写 入 。 由 禁
发 性 断 电 以 及 非 法 插 拔 都 将 对 Fah的存 储 造 成 灾 难 性 l s
的 影 响 ; 用 文 件 系 统 对 于 可 靠 性 的 设 计 考 虑 不 足 。第 通 2通 用文 件 系统 的记 录信 息 需 要 被 多次 改 写 ( F , 如 AT 表 ) 而 记 录 信 息 放 在 固 定 的 区 块 中 , 导 致 该 区 块 的 频 , 将
作 , 导 致 存 储 卡 使 用 寿 命 降 低 , 计 专 门 针 对 Fah存 而 设 ls
储 器 的文 件 系 统 是 必 要 的 。
引 入 了 日志结 构 的 思 想 , 中 J F x和 Y F S是 代 码 开 其 FS A F
源的 。
1 N N ls A D Fa h存 储 器 的特 点
于存 储 器 每 一 块 的 内部 结 构 都 是 相 互 独 立 的 , 块 并 不 影 坏
响 系统 的操 作 。
繁 使 用 , 响 整 个 Fah 件 的 使 用 寿 命 。第 3 Fah存 影 l 器 s ,l s
储 器 读 取 速 度 比磁 盘 驱 动 器 快 , 储 的 内 容 很 多 是 多 媒 存
Nand flash文件系统总结
NAND flash文件系统目前flash的文件系统比较多,用的比较多的就是JFFS2文件系统。
基于NOR flash上的JFFS2文件系统可以说算是比较成熟了,支持NAND flash的JFFS2也已经发布了。
源代码可以到上面下载。
但是在我的测试过程中,在nand flash上挂接的JFFS2文件系统很不稳定,经常有CRC错误产生。
特别是进行写操作的时候,每次复位都会产生CRC错误,可以说支持NAND flash的JFFS2文件系统目前还不成熟。
而YAFFS文件系统则是专门针对NAND flash的,源代码可以到/yaffs/index.html上下载。
在测试过程中稳定性能比JFFS2文件系统要稳定的多,而且mount分区的时间也比JFFS2文件系统少的多。
用JFFS2 mount一个2m的文件系统大约需要1s。
下面分别介绍在uclinux 下面使用JFFS2和YAFFS文件系统。
1、JFFS2到上面下载最新的MTD和JFFS2压缩包。
压缩包里面还有有关的内核补丁和一些MTD的相关工具。
主要的补丁就是ilookup-2.4.23.patch,因为最新的MTD驱动中要用到一个ilookup()函数。
打完补丁、更新了MTD驱动和JFFS2文件系统之后就开始写自己nand flash驱动了。
如果不想把JFFS2作为根文件系统的话,还需要修改MTD_BLOCK_MAJOR。
驱动可以参考里面的例子,最简单的就是参考spia.c。
写驱动主要工作是定义flash分区结构、定义flash读写地址、写控制flash 的**_hwcontrol()函数。
具体的操作要看所用的nand flash的芯片资料。
相对NOR flash来说驱动要简单多了。
:)改完之后再配置Memory Technology Devices(MTD)下CONFIG_MTD=YCONFIG_MTD_DEBUG=YCONFIG_MTD_DEBUG_VERBOSE=3CONFIG_MTD_PARTITIONS=YCONFIG_MTD_CHAR=YCONFIG_MTD_BLOCK=YNAND Flash Device Drivers下CONFIG_MTD_NAND=Y定义自己的驱动文件File systems下CONFIG_JFFS2_FS=YCONFIG_JFFS2_FS_DEBUG=2CONFIG_JFFS2_FS_NAND=y /*这个是新加的*/在uClinux v1.3.4 Configuration下Flash Tools下CONFIG_USER_MTDUTILS=YCONFIG_USER_MTDUTILS_ERASE=YCONFIG_USER_MTDUTILS_ERASEALL=YCONFIG_USER_MTDUTILS_MKFSJFFS2=Y最后就是辛苦了调试工作了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在Nand Flash上构建FAT文件系统摘要:本文介绍了Nand Flash存储器的结构,介绍了Fat文件系统的结构,介绍了Nand Flash 基础上实现Fat文件系统的初步构想,分析了工作中的难点。
是对之前阅读FA T文件系统资料工作的总结。
目录1Nand Flash的结构 (3)1.1Nand Flash一般结构 (3)1.2Nand Flash数据完整性 (4)1.3建立在Flash上的文件系统的要求 (4)2FA T文件系统 (5)2.1FA T文件系统简介 (5)2.2FA T文件系统的组成 (5)2.2.1引导扇区 (5)2.2.2保留扇区 (7)2.2.3FA T表和数据的存储原则 (7)3Nand Flash上的文件系统 (13)4工作分析 (14)5参考文献: (15)1Nand Flash的结构1.1Nand Flash一般结构Flash是一种非易失性的存储器,允许用户进行电擦除和电写入。
NOR和NAND是现在市场上两种主要的非易失闪存技术。
NOR的特点是芯片内执行(XIP, eXecute In Place),应用程序可直接在flash闪存内运行,传输效率很高,很低的写入和擦除速度。
NAND结构能提供极高的单元密度,可以达到高存储密度,并且写入和擦除的速度也很快。
应用NAND的困难在于flash的管理和需要特殊的系统接口。
K9F2808U0C是Sunsang公司的一块16MB 的Nand Flash芯片,其结构图如图1.1所示,Flash按照结构分为,区(Partion),块(Block),扇区(Sector)。
该Flash芯片的列地址被分为3种,A区(0-255byte),B区(256-511byte),C区(512-527byte)图1.1 K9F2808U0C结构图Flash设备的编程只允许从1写到0,而不能将某位数据从0写到1,只能通过擦除的方式将一整块的数据写为1,如图1.2所示。
图1.2 Flash设备写入特点1.2Nand Flash数据完整性Nand Flash 使用中要数据完整性,主要有两个因素的影响:1)Flash中的坏块,可能在出场的时候Flash设备中就存在坏块,也可能随着Flash设备的使用,在使用的某刻,出现坏块。
但块与块之间是独立的,某Flash设备中出现坏块不影响其它块的使用。
处理方法是建立和维持一个坏块的列表,使用软件进行坏块的检测和屏蔽;2)写操作时因掉电而造成的数据的丢失。
通过文件系统来处理这一问题。
1.3建立在Flash上的文件系统的要求1)写分布。
由于每块都是独立的,具有有限的擦写次数,因此在进行写入或者擦除时避免一直对某块进行反复的擦写,而应将对Flash设备的擦除或者写入分布到所有的块中;2)存储回收。
改动的数据往往并不是被写回原有的块中,而是写到一个新的可编程的块中,这就需要对原有的块进行回收,以使其变成新的可编程的块;3)读写同时进行。
对于多分区的Flash,可以在对某区进行读的同时,对另一区进行写操作。
如果是同时对某分区进行读写操作,只能通过软件进行控制;4)对Flash设备的统一管理。
使用软件的方法能将不同的Flash统一管理。
2FAT文件系统2.1FAT文件系统简介FA T文件系统是File Allocation Table的简称,一共有三种,分别是FAt12、FA T16、FA T32。
FA T12是最早的FA T文件系统,伴随着Dos诞生,在DOS3.0以前使用,采用12位文件分配表,Fat12可以管理的磁盘容量是8M,现在主要用在软盘驱动器中。
Fat12文件系统有如下限制:1) 文件名:只能是8.3格式的文件名;2) 磁盘容量:最多8M(4096clusters×4sectors/clusters×512bytes/sectors);3) 文件碎片严重。
在Dos3.0中,微软推出了新的文件系统Fat16。
除了采用了16位字长的分区表之外,Fat16和Fat12在其他地方都非常的相似。
字长增加4位,可以使用的簇的总数增加到了65546=216。
在总的簇数在4096之下的时候,应用的还是Fat12的分区表,当实际需要超过4096簇的时候,应用的是Fat16的分区表。
FA T16分区格式存在严重的缺点:大容量磁盘利用效率低。
为了解决磁盘浪费问题,微软推出了一种全新的磁盘分区格式FA T32,应用在Windows 95 OSR2及以后的Windows 版本中。
这种格式采用32位的文件分配表,磁盘的管理能力大大增强,突破了FA T16 2GB的分区容量的限制。
FA T32的限制:1)最大的限制在于兼容性方面,Fat32不能保持向下兼容。
2)当分区小于512M时,Fat32不会发生作用。
4)单个文件不能大于4G。
(精确数据是4G-2bytes)。
2.2FAT文件系统的组成每个FA T文件系统由4部分组成,这些基本区域按照一下顺序排列:0 -保留区(Reserved Region)1 -FA T区(FA T Region)2 -根目录区(Root Directory Region,FA T32卷没有此域)3 -文件和目录数据区(File and Directory Data Region)下面依次解释DBR、FA T1、FA T2、根目录、数据区、剩余扇区的概念。
2.2.1引导扇区引导扇区,又叫DBR区(DOS BOOT RECORD)即操作系统引导记录区的意思,通常占用分区的第0扇区共512个字节。
在这512个字节中,其实又是由跳转指令,厂商标志和操作系统版本号,BPB(BIOS Parameter Block),扩展BPB,OS引导程序,结束标志几部分组成,以FA T32为例说明分区DBR各字节的含义,见图2.1。
图2.1 FA T32分区DBR扇区图2.1的对应解释见图2.2图2.2 FA T32上DBR扇区解释详细的DBR扇区各字段的偏移及解释参见FA T file system specification。
2.2.2保留扇区在上述FA T文件系统DBR的偏移0x0E处,用2个字节存储保留扇区的数目。
所谓保留扇区(有时候会叫系统扇区,隐藏扇区),是指从分区DBR扇区开始的仅为系统所有的扇区,包括DBR扇区。
在FA T16文件系统中,保留扇区的数据通常设置为1,即仅仅DBR 扇区。
而在FA T32中,保留扇区的数据通常取为32。
FA T32中的保留扇区除了磁盘总第0扇区用作DBR,总第2扇区(win98系统)或总第0xC 扇区(win2000,winxp)用作OS引导代码扩展部分外,其余扇区都不参与操作系统管理与磁盘数据管理,通常情况下是没作用的。
操作系统之所以在FA T32中设置保留扇区,是为了对DBR作备份或留待以后升级时用。
FA T32中,DBR偏移0x34占2字节的数据指明了DBR 备份扇区所在,一般为0x06,即第6扇区。
当FA T32分区DBR扇区被破坏导致分区无法访问时。
可以用第6扇区的原备份替换第0扇区来找回数据。
2.2.3FAT表和数据的存储原则FA T表(File Allocation Table 文件分配表),是Microsoft在FA T文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。
在FA T文件系统中,文件的存储依照FA T表制定的簇链式数据结构来进行。
同时,FA T文件系统将组织数据时使用的目录也抽象为文件,以简化对数据的管理。
FA T表项的大小与FA T类型有关,FA T12的表项是12bit,FA T16为16bit,FA T32为32bit。
我们把数据区空间分成BPB_BytsPerSec*BPB_SecPerClus字节长的簇来管理,对于大文件,需要分配多个簇,同一个文件的数据并不一定完整的存放在磁盘上一个连续的区域内,而往往会分成若干段,象链子一样存放。
这种存放方式称为文件的链式存储。
为了实现文件的链式存储,文件系统必须准确的记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继内容的下一个簇的簇号,对文件的最后一簇,则要指明本簇无后继簇。
这些都是由FA T表来保存的,FA T表的对应表项中记录着它所代表的簇的有关信息:诸如是否空,是否是坏簇,是否已经是某个文件的尾簇等。
FAT16存储原理当把一部分磁盘空间格式化为fat文件系统时,fat文件系统就将这个分区当成整块可分配的区域进行规划,以便于数据的存储。
1扇区实际情况取大小同FAT132个扇区开始簇编号(从2开始)不足一簇图2.3 FA T12/16 文件系统组织形式FA T16是Microsoft较早推出的文件系统,具有高度兼容性,目前仍然广泛应用于个人电脑尤其是移动存储设备中。
FA T16简单来讲由图2.3所示的6部分组成(主要是前5部分)。
首先是引导扇区(DBR),已经说过,FA T16在DBR之后没有留有任何保留扇区,其后紧随的便是FA T表。
FA T表是FA T16用来记录磁盘数据区簇链结构的。
FA T将磁盘空间按一定数目的扇区为单位进行划分,这样的单位称为簇。
通常情况下,每扇区512字节的原则是不变的。
簇的大小一般是2n (n为整数)个扇区的大小,像512B,1K,2K,4K,8K,16K,32K,64K。
实际中通常不超过32K。
之所以簇为单位而不以扇区为单位进行磁盘的分配,是因为当分区容量较大时,采用大小为512b的扇区管理会增加fat表的项数,对大文件存取增加消耗,文件系统效率不高。
FA T16分区中簇的大小的取值是有关系的,见图2.4。
格式化FA T16分区时,格式化程序根据分区的大小确定簇的大小,然后根据保留扇区的数目、根目录的扇区数目、数据区可分的簇数与FA T表本身所占空间来确定FA T表所需的扇区数目,然后将计算后的结果写入DBR的相关位置。
FA T16 DBR参数的偏移0x11处记录了根目录所占扇区的数目(记录了根目录所包括的目录项数,每项32Byte)。
偏移0x16记录了FA T表所占扇区的数据。
偏移0x10记录了FA T 表的副本数目。
系统在得到这几项参数以后,就可以确定数据区的开始扇区偏移了。
FA T16文件系统从根目录所占的32个扇区之后的第一个扇区开始以簇为单位进行数据的处理,这之前仍以扇区为单位。
对于根目录之后的第一个簇,系统并不编号为第0簇或第1簇(可能是留作关键字的原因吧),而是编号为第2簇,也就是说数据区顺序上的第1个簇也是编号上的第2簇。
FA T表实际上是一个数据表,以2个字节为单位,我们暂将这个单位称为FA T记录项,通常情况其第1、2个记录项(前4个字节)用作介质描述。
从第三个记录项开始记录除根目录外的其他文件及文件夹的簇链情况。