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

📄 fat12.c

📁 FAT12 文件系统,囊括了文件系统的各个函数,另外还包括了地址映射,适合读写NAND_FLASH
💻 C
📖 第 1 页 / 共 5 页
字号:
			NAND_SpareRead(i<<14 | 2, &tempSectorSpare[2], 6);
			if((tempSectorSpare[5] == 0xff) && (tempSectorSpare[7] == 0xff) && (tempSectorSpare[2] == 0xff))		
			{	//该块非坏块并且为空
				newblocknum = i;
				full = 0;
				break;														//找到好块,退出该循环
			}
		}
	}
	if((startPhblock >= (FAT_SIZEOFWORD-1)) || (full == 0xff))				//不能向后或向后没有找到新块,再从前找
	{
		for(i=0; i<startPhblock; i++)
		{
			NAND_SpareRead(i<<14 | 2, &tempSectorSpare[2], 6);
			if((tempSectorSpare[5] == 0xff) && (tempSectorSpare[7] == 0xff) && (tempSectorSpare[2] == 0xff))		
			{	//该块非坏块并且为空
				newblocknum = i;
				full = 0;
				break;														//找到好块,退出该循环
			}
		}
	}
	
	if(full == 0xff)														//FLASH满,没有空的块
	{	
		i = 0;
		do																	//清理一个垃圾块
		{
			newblocknum = GarbageProcess( );
			if(newblocknum != 0xffff)
			{	return 	 newblocknum;	}									//找到一个,返回
			
		}while((newblocknum== 0xffff) && (i++ < (FAT_SIZEOFWORD-1)));
	
	}
	
	return 	 newblocknum;
}


/******************************* 函数 WORD Find_BlankLogicBlock( ) **********************************/
/* 功能:从逻辑块号0开始,在FAT表中寻找一个空逻辑块,找到之后返回新的逻辑块号						*/
/* 寻找策略:逻辑映射表中如果某个逻辑块号对应的物理块号值是0xffff,说明该逻辑号还没有相应的物理块,	*/
/*			 为空,此时即找到,返回该逻辑块号													    */
/* 入口参数:无																						*/
/* 返回值:找到的空逻辑块号. 0xffff表示找不到空逻辑块,盘已满										*/
/* 说明:非用户使用函数																				*/
/****************************************************************************************************/
WORD Find_BlankLogicBlock( )//OK
{
	DWORD oldsector,newsector;
	BYTE* psector;
	BYTE* neednext;
	WORD  buff;
	BYTE  tempbuffer1[512],tempbuffer2[512];
	WORD  fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
	WORD  clusternum,clustervalue;  
	WORD  offsetinsector;
	

	oldsector = 0;
		
	for(clusternum=2; clusternum<(DISK_48M<<6); clusternum++)
	{
		fatoffset = clusternum + clusternum/2;
		offsetinsector = fatoffset % BytesPerSector;
		newsector = fatoffset/BytesPerSector + FirstFATSector;
			
		if(newsector != oldsector)
		{	
			ReadLgSector(newsector,tempbuffer1);
			oldsector = newsector;
		}
		
		if(offsetinsector != (BytesPerSector - 1))			//逻辑簇号未跨扇区,直接读取
		{	
			psector = &tempbuffer1[offsetinsector];
			buff = ((word)(*(psector+1))<<8) | *psector;
		}
		else if(newsector < (FirstFATSector+FATsectors-1))	//逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要组合形成逻辑簇号									
		{
			psector = &tempbuffer1[offsetinsector];
			neednext= ReadLgSector(newsector+1,tempbuffer2);
			buff = ((word)(*neednext)<<8) | *psector;
		}
		else												//逻辑簇号是最后一个FAT扇区的最后一个字节并且需要跨扇区,说明到头
		{	return 0xffff;	}
		
		if(clusternum&0x01)									//簇号是奇数,取psector中的高12位
		{	clustervalue = buff>>4;	}
		else												//簇号是偶数,取psector中的低12位
		{	clustervalue = buff & 0x0fff;	}
		
		if(clustervalue == 0)
		{	return clusternum;	}							//返回找到的空逻辑簇
	}
		
	return 0xffff;											//未找到空簇
}




/***************************** 函数 WORD Read_FAT(WORD LgClusterNum) ********************************/
/* 功能:	读取FAT表中对应输入逻辑块号下的值														*/
/* 入口参数:WORD LgClusterNum----逻辑簇号															*/
/* 返回值:FAT表中逻辑块号下的值. 0xffff表示输入的逻辑块号超出FAT表的逻辑块范围						*/
/* 说明:非用户使用函数																				*/
/****************************************************************************************************/
WORD Read_FAT(WORD LgClusterNum)//OK
{
	DWORD sectornum;
	BYTE* psector;
	BYTE* neednext;
	WORD  buff;
	BYTE  tempbuffer1[3],tempbuffer2[3];
	WORD  fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
	WORD  clustervalue;  
	WORD  offsetinsector;
	
	fatoffset = LgClusterNum + LgClusterNum/2;
	offsetinsector = fatoffset % BytesPerSector;
	sectornum = fatoffset/BytesPerSector + FirstFATSector;
			
	if(ReadLgSectorFat(sectornum,tempbuffer1,offsetinsector)==NULL)
	{	return 0xffff;	}
		
	if(offsetinsector != (BytesPerSector - 1))			//逻辑簇号未跨扇区,直接读取
	{	
		psector = &tempbuffer1[0];
		buff = ((word)(*(psector+1))<<8) | *psector;
	}
	else if(sectornum < (FirstFATSector+FATsectors-1))	//逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要组合形成逻辑簇号									
	{
		psector = &tempbuffer1[0];
		neednext= ReadLgSectorFat(sectornum+1,tempbuffer2,0);
		if(neednext==NULL)
		{
		 return 0xffff; 
		}
		buff = ((word)(*neednext)<<8) | *psector;
	}
	else												//逻辑簇号是最后一个FAT扇区的最后一个字节并且需要跨扇区,说明到头
	{	return 0xffff;	}
		
	if(LgClusterNum&0x01)								//簇号是奇数,取psector中的高12位
	{	clustervalue = buff>>4;	}
	else												//簇号是偶数,取psector中的低12位
	{	clustervalue = buff & 0xfff;	}
		
	return clustervalue;								//返回逻辑簇号下的内容
}

/*WORD Read_FAT(WORD LgClusterNum)
{
	DWORD sectornum;
	BYTE* psector;
	BYTE* neednext;
	WORD  buff;
	BYTE  tempbuffer1[512],tempbuffer2[512];
	WORD  fatoffset;
	WORD  clustervalue;  
	WORD  offsetinsector;
	
	fatoffset = LgClusterNum + LgClusterNum/2;
	offsetinsector = fatoffset % BytesPerSector;
	sectornum = fatoffset/BytesPerSector + FirstFATSector;
			
	ReadLgSector(sectornum,tempbuffer1);
		
	if(offsetinsector != (BytesPerSector - 1))			
	{	
		psector = &tempbuffer1[offsetinsector];
		buff = ((word)(*(psector+1))<<8) | *psector;
	}
	else if(sectornum < (FirstFATSector+FATsectors-1))								
	{
		psector = &tempbuffer1[offsetinsector];
		neednext= ReadLgSector(sectornum+1,tempbuffer2);
		buff = ((word)(*neednext)<<8) | *psector;
	}
	else												
	{	return 0xffff;	}
		
	if(LgClusterNum&0x01)								
	{	clustervalue = buff>>4;	}
	else												
	{	clustervalue = buff & 0xfff;	}
		
	return clustervalue;								
}*/

 
 
/************************** 函数 void Write_FAT(WORD LgClusterNum,WORD Value) ***********************/
/* 功能:	将数值Value写入FAT表中对应输入逻辑块号LgSectorNum下										*/
/* 入口参数:WORD LgClusterNum----逻辑簇号															*/
/*			WORD Value----准备写入的数值															*/
/* 返回值:	FAT表中逻辑块号下的值. 0xffff表示输入的逻辑块号超出FAT表的逻辑块范围					*/
/* 说明:	非用户使用函数																			*/
/****************************************************************************************************/
void Write_FAT(WORD LgClusterNum,WORD Value)//OK
{
	DWORD sectornum;
	BYTE  tempbuffer1[512],tempbuffer2[512];
	WORD  fatoffset;//逻辑簇号在整个FAT表中的字节偏移位置
	WORD  offsetinsector;
	
	fatoffset = LgClusterNum + LgClusterNum/2;
	offsetinsector = fatoffset % BytesPerSector;
	sectornum = fatoffset/BytesPerSector + FirstFATSector;
			
	ReadLgSector(sectornum,tempbuffer1);
		
	if(offsetinsector != (BytesPerSector - 1))			//逻辑簇号未跨扇区,直接写入
	{	
		if(LgClusterNum&0x01)							//簇号是奇数,写入逻辑簇号中的高12位
		{	
			tempbuffer1[offsetinsector] = (tempbuffer1[offsetinsector]&0x0f)|((Value&0x000f)<<4);
			tempbuffer1[offsetinsector+1] = (BYTE)((Value&0x0ff0)>>4);
		}
		else											//簇号是偶数,写入逻辑簇号中的低12位
		{	
			tempbuffer1[offsetinsector] = (BYTE)(Value&0x00ff);
			tempbuffer1[offsetinsector+1] = (tempbuffer1[offsetinsector+1]&0xf0)|((Value&0x0f00)>>8);
		}
		WriteLgSector(sectornum,tempbuffer1);			//写入FAT1
		WriteLgSector(sectornum+FATsectors,tempbuffer1);//写入FAT2
	}
	else if(sectornum < (FirstFATSector+FATsectors-1))	//逻辑簇号跨了扇区并且不是最后一个FAT扇区,需要分两次写入不同的扇区									
	{
		ReadLgSector(sectornum+1,tempbuffer2);
		if(LgClusterNum&0x01)							//簇号是奇数,写入逻辑簇号中的高12位
		{	
			tempbuffer1[offsetinsector] = (tempbuffer1[offsetinsector]&0x0f)|((Value&0x000f)<<4);
			tempbuffer2[0] = (BYTE)((Value&0x0ff0)>>4);
		}
		else											//簇号是偶数,写入逻辑簇号中的低12位
		{	
			tempbuffer1[offsetinsector] = (BYTE)(Value&0x00ff);
			tempbuffer2[0] = (tempbuffer2[0]&0xf0)|((Value&0x0f00)>>8);
		}
		WriteLgSector(sectornum,tempbuffer1);			//写入FAT1
		WriteLgSector(sectornum+FATsectors,tempbuffer1);//写入FAT2
		WriteLgSector(sectornum+1,tempbuffer2);			//写入FAT1
		WriteLgSector(sectornum+1+FATsectors,tempbuffer2);//写入FAT2
	}

	return ;								
} 
 
 
 
 
/************************************ 函数unsigned char GetFatInfo(void) ****************************/
/*函数功能:该函数主要用于从已有的存储介质中获得文件系统信息										*/
/*函数输出:得到以下变量的值:																		*/
/*          SectorsPerCluster																		*/
/*			BytesPerSector																			*/
/*		    FirstFATSector																			*/
/*     		FATsectors																				*/
/*     		FirstDataSector																			*/
/*     		RootDirCount																			*/
/*     		RootDirSectors																			*/
/*			FirstDirSector																			*/
/* 说明:   用户使用函数																			*/
/****************************************************************************************************/
 void GetFatInfo(void)//OK
 {
     BOOTSECTOR50 *bootsector; 
	 BPB50 *bpb;
	 EXTBOOT *ext;
	 BYTE tempbuffer[512];
	 	 
     NAND_PageRead(lgToph[0]<<14, tempbuffer, 512);			//读引导扇区DBR
     bootsector = (BOOTSECTOR50 *)tempbuffer;
	 bpb = (BPB50 *)(bootsector->Bs_BPB);
	 ext = (EXTBOOT *)(bootsector->Bs_Ext);
     
     SectorsPerCluster   = bpb->BPB_SecPerClust;							//每cluster的sector数目32
     if(SectorsPerCluster==0) return;
     BytesPerSector      = bpb->BPB_BytesPerSec;							//每sector的字节数512
     if(BytesPerSector==0) return;
     RootDirCount 		 = bpb->BPB_RootEntCnt;								//根目录的目录项数496
     RootDirSectors		 = (RootDirCount*sizeof(DIRENTRY))/BytesPerSector;	//根目录区所占用的扇区数 = 31
     FirstFATSector      = bpb->BPB_RsvdSecCnt;								//FAT区的起始地址 =1
     FATsectors          = bpb->BPB_FATSz16;								//每个FAT表的扇区数,16
     if(bpb->BPB_FATSz16)
     {
         //BPB_FATSz16 is non-zero and is therefore valid
         FirstDirSector = FirstFATSector + bpb->BPB_NumFATs * FATsectors ;	//=33
     }
     
     FirstDataSector  	 = FirstDirSector + RootDirSectors;					//第一个数据扇区的位置 =64
 
 	 
 }
 
 

/************************ 函数 WORD AllocCluster(WORD PrevLgClusterNum) *****************************/
/* 功能:寻找并分配一个空逻辑镞和空物理块,将该物理块映射到逻辑块(更新逻辑映射表) 					*/
/*		 并在FAT表中将新的逻辑镞号链接到先前的逻辑镞号后,新逻辑簇号标记为0x0fff(文件最后一簇)		*/
/* 入口参数:先前的逻辑镞号,0表示没有先前的逻辑镞号												*/
/* 返回值:新分配的镞号. 0xffff表示找不到空镞,盘已满												*/
/* 说明:非用户使用函数																				*/
/****************************************************************************************************/
WORD AllocCluster(WORD PrevLgClusterNum)//OK
{
	WORD newlogicClusternum;
	WORD newphBlocknum;
	BYTE tempSectorSpare[16];
	
	/*********** 64M的NAND_FLASH共有4096个块,因此镞的最大编号是4095 ****************/
	/* 首先在FAT表中寻空逻辑号*/
	newlogicClusternum = Find_BlankLogicBlock( );
	if(newlogicClusternum == 0xffff)
	{	return 0xffff;	}
	
	newphBlocknum = Find_BlankPhBlock(lgToph[PrevLgClusterNum]+1);			
	if(newphBlocknum == 0xffff)
	{	return 0xffff;	}

⌨️ 快捷键说明

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