⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.cpp

📁 Nand flash FAT16 文件系统源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 * update 2008/12/1
 *
 * ycdbox@126.com  1
 */
LOCAL int Open_ReadOnly(BYTE *pDir)
{
	int			hFile = 0;
	DIR_ENTRY_T *pDirEntry = (DIR_ENTRY_T *)pDir;
	FCB_T		*pPCB;

	pPCB = AlocalFCB();
	if(pPCB){

		//gFS_FCB[i].mDevName;						//盘名:cdefg..z
		memcpy(pPCB->mFileName,pDirEntry->name,11);//文件名
		pPCB->mFileLen = pDirEntry->size;		//文件长度
		pPCB->mSequenceNum = 0;					//块顺序号
		pPCB->mOffset= 0;						//偏移量
		pPCB->mStartFatNo = pDirEntry->start;	//文件起始块FAT号
		pPCB->mCurFatNo = pDirEntry->start;	//文件当前块FAT号
		pPCB->mBlockSize = gFS_Device.mBlockSize;//块大小
		//gFS_FCB[i].mBlockBuf;						//块缓冲
		pPCB->mState = 1;					//使用状态
		pPCB->mUpdate = 0;					//待刷新
		pPCB->mMode = eFILE_MODE_R;			//打开模式
		hFile = pPCB->mHandle; 			//文件句柄
		
		FS_ReadBlock(pPCB->mStartFatNo,pPCB->mBlockBuf,NULL);
	}

	return( hFile );
}




/**
 * LOCAL int Open_WriteOnly(BYTE *pDir)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  1
 */
LOCAL int Open_WriteOnly(BYTE *pDir)
{
	int			hFile = 0;
	DIR_ENTRY_T *pDirEntry = (DIR_ENTRY_T *)pDir;
	FCB_T		*pPCB;

	pPCB = AlocalFCB();
	if( pPCB ){
		pDirEntry->start = GetNULLFatNo();
		if(0 != pDirEntry->start){
			//(1)
			SetNextFat(pDirEntry->start, FS_FAT_END);
			
			//(2)
			pDirEntry->size = 0;

			//(3)
			memcpy(pPCB->mFileName,pDirEntry->name,11);//文件名
			pPCB->mFileLen = pDirEntry->size;		//文件长度
			pPCB->mSequenceNum = 0;					//块顺序号
			pPCB->mOffset = 0;						//偏移量
			pPCB->mStartFatNo = pDirEntry->start;	//文件起始块FAT号
			pPCB->mCurFatNo = pDirEntry->start;	//文件当前块FAT号
			pPCB->mBlockSize = gFS_Device.mBlockSize;//块大小
			//gFS_FCB[i].mBlockBuf;						//块缓冲
			pPCB->mState = 1;					//使用状态
			pPCB->mUpdate = 1;					//待刷新
			pPCB->mMode = eFILE_MODE_W;			//打开模式
			hFile = pPCB->mHandle; 			//文件句柄
		}
		else{
			pDir[0]=0;
		}
	}
	else{
		pDir[0]=0;
	}
	
	return( hFile );
}



/**
 * LOCAL int FS_Read(BYTE *Buf,int size,int items,int hFile)
 *
 * 读数据
 *
 * upate 2009/1/18
 *
 * ycdbox@126.com   1
 */
LOCAL int FS_Read(BYTE *Buf,int size,int items,int hFile)
{
	uint32 		Len;
	uint32		Point;
	uint32		Offset;
	uint32		Count = 0;
	uint16		NextFat;
	FCB_T		*pFCB;

	
	//不在该盘
	if( !FS_IsIn( hFile ) ){
		return( Count );
	}

	//文件未打开
	pFCB = GetFileFCB( hFile ); 
	if(0 == pFCB->mState){
		return( Count );
	}

	//只写
	if( eFILE_MODE_W == pFCB->mMode){
		return( Count );
	}

	//文件尾
	Point = pFCB->mSequenceNum*pFCB->mBlockSize+pFCB->mOffset;
	if(Point >= pFCB->mFileLen){
		return( Count );
	}

	
	//有效长度
	Len = size * items;
	if(Len > (pFCB->mFileLen-Point)){
		Len = pFCB->mFileLen-Point;
	}
	
	//读数据
	Offset = pFCB->mOffset;
	while(Count < Len){
		if(Offset >= pFCB->mBlockSize){
			if(FS_FAT_END != pFCB->mCurFatNo){
				NextFat = GetNextFat(pFCB->mCurFatNo);
				FS_ReadBlock(NextFat,pFCB->mBlockBuf,NULL);
				pFCB->mCurFatNo = NextFat;
				pFCB->mSequenceNum++;
				Offset = 0;
			}
			else{
				break;
			}
		}
		*Buf = pFCB->mBlockBuf[Offset];
		Buf++;
		Offset++;
		Count++;
	}
	pFCB->mOffset = Offset;
	
	return( Count );
}






/**
 * LOCAL bool FS_WriteBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
 *
 * 按FAT号写(相对地址)
 *
 * upate 2009/1/18
 *
 * ycdbox@126.com  1
 */
LOCAL bool FS_WriteBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
{
	uint32		BlockNo;
	bool        Result;

	//转为Flash物理地址写(绝对地址)
	BlockNo = Fat + gFS_Device.mFirstBockNo;
	Result = NF_WriteBlock(BlockNo,Buf,Info);

	return( Result );
}



/**
 * LOCAL bool FS_ReadBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
 *
 * 按FAT号写(相对地址)
 *
 * upate 2009/1/18
 *
 * ycdbox@126.com  1
 */
LOCAL bool FS_ReadBlock(uint16 Fat,BYTE *Buf,BYTE *Info)
{
	uint32		BlockNo;
	bool        Result;
	int         i;

	//转为Flash物理地址写(绝对地址)
	BlockNo = Fat + gFS_Device.mFirstBockNo;
	for(i=0; i<3; i++){
		Result = NF_ReadBlock(BlockNo,Buf,Info);
		if(true == Result){
			break;
		}
	}
	
	return( Result );
}


/**
 * LOCAL int FS_Write(BYTE *Buf,int size,int items,int hFile)
 *
 *	 一.
 *		(1)保存
 *		(2)Next
 *
 *	 二.
 *
 *		(1)mPrev.
 *		(2)mCur
 *
 *
 *	 三.
 *		(1)cur
 *		(2)Next
 *
 *
 *
 *1.(a)mPrev->Cur
 *	(b)mCur->0
 *	(c)Cur->Next
 *	(d)Next不变或fff8
 *
 *
 *
 *2.(a)mPrev = Cur
 *	(b)mCur = Next
 *
 *
 *
 *3.(a)Seq++.
 *	(b)office =0
 *
 *
 *
 */
LOCAL int FS_Write(BYTE *Buf,int size,int items,int hFile)
{
	uint32		Total;
	uint32		Offset;
	uint16      NextFAT;
	uint32      Count=0;
	uint32      FileSize;
	FCB_T		*pFCB;

	//不在该盘
	if( !FS_IsIn( hFile ) ){
		return( Count );
	}

	//文件未打开
	pFCB = GetFileFCB( hFile ); 
	if(0 == pFCB->mState){
		return( Count );
	}


	//只读保护
	if(eFILE_MODE_R == pFCB->mMode){
		return( Count );
	}

	
	Offset =  pFCB->mOffset;
	Total = size*items;
	
	while(Count < Total){
		if(Offset >= pFCB->mBlockSize){
			
			FS_FileFlush( pFCB );
			
			//Next(新的出来)
			NextFAT = GetNextFat(pFCB->mCurFatNo);
			if(FS_FAT_END == NextFAT){
				NextFAT =	GetNULLFatNo();
				if(0 == NextFAT){
					break;
				}
				SetNextFat(NextFAT,FS_FAT_END);
				SetNextFat(pFCB->mCurFatNo,NextFAT);
			}
			else{
				FS_ReadBlock(NextFAT,pFCB->mBlockBuf,NULL);
			}

			//mCur = Next新当前
			pFCB->mCurFatNo = NextFAT;

			
			//调整 Seq++  office =0
			pFCB->mSequenceNum++;
			Offset = 0;
		}
		
		pFCB->mBlockBuf[Offset] = *Buf;
		Offset++;
		Buf++;
		Count++;
		pFCB->mUpdate = 1;
	}
	pFCB->mOffset =  Offset;

	
	//文件长度
	FileSize = pFCB->mSequenceNum*pFCB->mBlockSize + pFCB->mOffset;
	if(FileSize > pFCB->mFileLen){
		pFCB->mFileLen = FileSize;
	}

	return( Count );
}





/**
 * LOCAL void FS_FileFlush(FCB_T* pFCB)
 *
 * 按FAT号写(相对地址)
 *
 * upate 2009/1/18
 *
 * ycdbox@126.com  1
 */
LOCAL void FS_FileFlush(FCB_T* pFCB)
{
	BYTE	SectorInfo[BLOCK_INFO_LEN];
	uint16  Fat;
	uint16  Next;
	uint16  Prev; 


	
	FS_WriteBlock(pFCB->mCurFatNo,pFCB->mBlockBuf,NULL);
	FS_ReadBlock(pFCB->mCurFatNo,NULL,SectorInfo);
	if(0xff == SectorInfo[SECTOR_BAD_INDEX]){
		return;
	}
	Next = GetNextFat(pFCB->mCurFatNo);
	SetNextFat(pFCB->mCurFatNo,FS_FAT_BAD);
			
	
	while( 1 ){
		Fat = GetNULLFatNo();
		if( !Fat ){//没有空块
			return;
		}
		
		FS_WriteBlock(Fat,pFCB->mBlockBuf,NULL);
		FS_ReadBlock(Fat,NULL,SectorInfo);
		
		if(0xff == SectorInfo[SECTOR_BAD_INDEX]){
			break;
		}
		
		SetNextFat(Fat,FS_FAT_BAD);
	}
	
	
	if(pFCB->mSequenceNum == 0){
		pFCB->mStartFatNo = Fat;
		pFCB->mCurFatNo   = Fat;
		SetNextFat(Fat,Next);
	}
	else{
		SetNextFat(Fat,Next);
		Prev = GetPrevFat(pFCB);
		SetNextFat(Prev,Fat);
		pFCB->mCurFatNo = Fat;
	}
}




/**
 * LOCAL void FS_RootFlush(void)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  1
 */
LOCAL void FS_RootFlush(void)
{
	int		Count;
	int		i,Index;
	int		Bad[2];
	BYTE    blkInfo[BLOCK_INFO_LEN];


	if( !gFS_FATParam.mUpdate ){
		return;
	}
	
	gFS_FATParam.mUpdate = 0;
	
	Bad[0] = 0;
	Bad[1] = 0;
	Count =	(gFS_FATParam.mCount>2) ? (2) : (gFS_FATParam.mCount);
	
	for(i=0; i<Count; i++){
		FS_WriteBlock(gFS_FATParam.mFatBlock[i], (BYTE*)gFS_FATBuf,NULL);
		FS_ReadBlock(gFS_FATParam.mFatBlock[i],NULL,blkInfo);
		if(0xff != blkInfo[SECTOR_BAD_INDEX]){
			Bad[i] = 1;
		}
	}

	//仅一个可用块不做了.
	if(Count <2) {
		return;
	}

	//两可用
	if(0 == Bad[0] && 
	  (0 ==	Bad[1])){
		return;
	} //一个可用
	else if((0 == Bad[0]) &&
		    (1 == Bad[1]) ){
		Count = 1;
	} //一个可用
	else if((1 == Bad[0]) &&
		    (0 == Bad[1]) ){
		gFS_FATParam.mFatBlock[0] = gFS_FATParam.mFatBlock[1];
		Count = 1;
	}//都坏了
	else {
		Count = 0;
	}

	
	//找到1到2个可以用的
	Index = Count;
	for(i=gFS_FATParam.mFatBlock[1]+1; i<FIRST_FILE_FAT; i++){
		FS_ReadBlock(i,NULL,blkInfo);
		if(0xff == blkInfo[SECTOR_BAD_INDEX]){
			gFS_FATParam.mFatBlock[Index] = i; 
			Index++;
			if(Index >= 2){
				break;
			}
		}				
	}

	//重写
	for(i=Count; i<Index; i++){
		FS_WriteBlock(gFS_FATParam.mFatBlock[i], (BYTE*)gFS_FATBuf,NULL);
	}

	//改数量
	gFS_FATParam.mCount = Index;
}



/**
 * LOCAL void FS_RootRead(void)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  1
 */
LOCAL void FS_RootRead(void)
{
	int		i;
	int     Count = 0;
	bool    Result;
	BYTE    blkInfo[BLOCK_INFO_LEN];

	//找到1到2个好的块.
	for(i=0; i<FIRST_FILE_FAT; i++){
		if(0 == Count){
			Result = FS_ReadBlock(i,(BYTE*)gFS_FATBuf,blkInfo);
		}
		else{
			Result = FS_ReadBlock(i,NULL,blkInfo);
		}
		
		if(true == Result && 0xff == blkInfo[SECTOR_BAD_INDEX]){
			gFS_FATParam.mFatBlock[Count] = i;
			Count++;
			if(Count >=2 ){ 
				break;
			}
		}
	}
	
	gFS_FATParam.mCount = Count;
}




/**
 * LOCAL int FS_Seek(int hFile,int offset,int set)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
LOCAL int FS_Seek(int hFile,int offset,int set)
{
	int			Result = 0;
	FCB_T		*pFCB;
	uint32      Point;
	uint16      Seq;
	uint16      n;
	uint16      off;
	uint16      Fat;

	//不在该盘
	if( !FS_IsIn( hFile ) ){
		return( Result );
	}

	//文件未打开
	pFCB = GetFileFCB( hFile ); 
	if(0 == pFCB->mState){
		return( Result );
	}
	
	switch( set ){
	case SEEK_SET:
		Point = offset;
		break;

	case SEEK_CUR:
		Point  = pFCB->mBlockSize*pFCB->mSequenceNum+pFCB->mOffset;
		Point += offset;
		break;

	case SEEK_END:
		Point = pFCB->mFileLen;
		Point += offset;
		break;
	};

	
	if(Point >= pFCB->mFileLen){
		Point =	pFCB->mFileLen;
		
		Seq = Point / pFCB->mBlockSize;
		off = Point % pFCB->mBlockSize;

		//文件尾所在块为单一块
		if(Seq>0 && off == 1){
			Seq--;
			off = pFCB->mBlockSize+1;
		}
	}
	else{
		Seq = Point / pFCB->mBlockSize;
		off = Point % pFCB->mBlockSize;
	}

	if(Seq !=  pFCB->mSequenceNum){
		//有写刷新
		if( pFCB->mUpdate ){
			FS_FileFlush( pFCB );
			pFCB->mUpdate =0;
		}

		//小于从0找
		if(Seq < pFCB->mSequenceNum){
			n = 0;
			Fat = pFCB->mStartFatNo;
		}
		else{ //大于从此找
			n = pFCB->mSequenceNum;
			Fat = pFCB->mCurFatNo;
		}
		
		while( n < Seq){
			Fat = GetNextFat( Fat );
			n++;
		}

		pFCB->mCurFatNo = Fat;
		pFCB->mSequenceNum = Seq;
		FS_ReadBlock(Fat,pFCB->mBlockBuf,NULL);
	}
	
	pFCB->mOffset = off;
	
	
	Result = 1;
	return( Result );
}




/**
 * LOCAL uint32 FS_Ftell(int hFile)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
LOCAL uint32 FS_Ftell(int hFile)
{
	uint32 Point = 0;
	FCB_T		*pFCB;

	//不在该盘
	if( !FS_IsIn( hFile ) ){
		return( Point );
	}

	//文件未打开
	pFCB = GetFileFCB( hFile ); 
	if(0 == pFCB->mState){
		return( Point );
	}
	
	Point = pFCB->mBlockSize*pFCB->mSequenceNum + pFCB->mOffset;

	return( Point );
}





/**
 * LOCAL int FS_Del(char *Name)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
LOCAL int FS_Del(char *Name)
{
	int		Result = 0;
	int		hFile = 0;
	char    c = toupper(Name[0]);
	char    File83Name[FILENAME_MAX_LEN];
	DIR_ENTRY_T    *pDir;
	uint16  Fat,NextFat;
	
	//解析文件名
	ParseFileNameTo83(Name,File83Name);
	
	//盘名
	if(c != gFS_Device.mDeviceName){
		return( Result );
	}

	//没文件名 c: 
	if(0 == File83Name[0]){
		return( Result );	
	}
	
	//已打开
	if(IsOpened(File83Name)){
		return( Result );
	}
	
	pDir = (DIR_ENTRY_T*)GetRootEntryAddr( File83Name );
	if(NULL == pDir){
		return( Result );
	}


	Fat = pDir->start;
	while( 1 ){
		NextFat = GetNextFat( Fat );	
		if(FS_FAT_BAD != NextFat){
			SetNextFat(Fat,	FS_FAT_NULL);
		}

		if(	FS_FAT_END == NextFat){
			break;
		}

		if(FS_FAT_BAD == NextFat){
			break;
		}

		Fat = NextFat;
	}

	FS_RootFlush();
	
	Result = 1; 

	return ( Result );
}



/**
 * LOCAL int FS_IsFormat(void)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
LOCAL int FS_IsFormat(void)
{
	int Result = 0;
	
	if(FS_FAT_FLAG == gFS_FATBuf[0]){
		Result = 1;
	}
	return ( Result );
}




/**
 * int FS_feof( int hFile)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
LOCAL int FS_feof( int hFile)
{
	int Result = 1;	
	uint32 Point = 0;
	FCB_T		*pFCB;

	//不在该盘
	if( !FS_IsIn( hFile ) ){
		return( Result );
	}

	//文件未打开
	pFCB = GetFileFCB( hFile ); 
	if(0 == pFCB->mState){
		return( Result );
	}
	
	Point = pFCB->mBlockSize*pFCB->mSequenceNum + pFCB->mOffset;

	if(Point < pFCB->mFileLen ){
		Result = 0;
	}

	return( Result );
}


LOCAL FILE_INTO_T gFlashDiskInfo={
	FS_Open,//int (*mFopen)(char *Name,char*mode);
	FS_Close,//int (*mFclose)(int hFile);
	FS_Read,//int (*mFread)(BYTE *buf,int n,int t,int hFile);
	FS_Write,//int (*mFwrite)(BYTE *buf,int n,int t,int hFile);
	FS_Seek,//int (*mFseek)(int hFile,int offset,int begin);
	FS_Ftell,//uint32 *mFtell(int hFile);
	FS_Format,//int (*mFomat)(char DevName);
	FS_Init,//int (*mFInit)(char DevName);
	FS_IsIn,//int (*mFIsIn)(int hFile);
	FS_Del,//int (*mFDel)(char *Name); 
	FS_IsFormat,//int (*mFIsFormat)(void);
	FS_feof
};




/**
 * int FS_AddFlashDisk( DISK_INFO_P *f)
 *
 * update 2008/12/1
 *
 * ycdbox@126.com  0
 */
int FS_AddFlashDisk( DISK_INFO_P *f)
{
	*f = &gFlashDiskInfo;

	return(1);
}




/*---------------------------------------------------------------------------------------*/







⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -