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

📄 dosfat.c

📁 一种文件系统的结构
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "..\define.h"
#include "..\all.h"


data	bit	gbt_FindFlag;

xdata	U8	gc_ClusBufValidSize;
xdata	U8	gc_ClusBufValidPoint;
xdata	U32	gdw_ClusterBuffer[8];
xdata	U32	gdw_FreeClusterNum[2];
xdata	U32	gdw_TotalFreeClusCounter;
xdata	U32	gdw_TotalFreeClusNumber;

void	MoveUSBtoUserDataBuf(U16 tw_StartAddr);
U8		DOS_ConnectFATChain(U32 tdw_HeadCluster, U32 tdw_TailCluster);
U8		DOS_Copy_FATtoFAT(U32 tdw_HeadCluster, U32 tdw_TailCluster, bit tbt_fat1tofat2);
U8		DOS_MarkFATUpdate(U32 tdw_MarkFATAddr,U8 tc_Value);
U8		DOS_SearchFreeCluster(U8 tc_SearchMode);
U32		DOS_ClusterLogicAddr(U32 tdw_Cluster);
U32		DOS_GetAFreeCluster(void);
U32		DOS_GetNextCluster(U32 tdw_CurrentCLuster, U32 tdw_ClusterNumber);


U32 DOS_ClusterLogicAddr(U32 tdw_Cluster)
{
	U32 tdw_LogicAddr;

	if (tdw_Cluster == 0)
	{//maybe Root dir
    	if (gc_DOS_FileSystemType == 2)
		{//FAT32 cluster can not be 0
			tdw_LogicAddr = 0;//mark error
		}
		else
		{//FAT12&FAT16 root dir
			tdw_LogicAddr = gdw_DOS_RootDirAddr;
		}
	}
	else if (tdw_Cluster == 1)
	{//cluster is disable to be 1
     //when cluster is 1,error is occur	
		tdw_LogicAddr = 0;
	}
	else
	{//normal state
		tdw_LogicAddr = (gdw_DOS_DataAddr) + ((tdw_Cluster - 2) * gc_DOS_SectorPerCluster);
	}

	return tdw_LogicAddr;
}
//-------------------------------------------------------------------------------
U8 DOS_ConnectFATChain(U32 tdw_HeadCluster, U32 tdw_TailCluster)
{
	U8	tc_Status;
	U8	tc_ValidPoint;
	U8	tc_ValidSize;
	U8	tc_ArrayNum;
	U8 	tc_ChainEndFlag = 0;
	U8	tc_ConnectMode;
	U8	tc_Dirty = 0;
	U16	tw_Offset;
	U32	tdw_CopyStartCluster;
	U32	tdw_CopyEndCluster;
	U32 tdw_CurrentCluster;
	U32 tdw_NextCluster;
	U32	tdw_CurrentSector;
	U32 tdw_NextSector;
	U32 tdw_TempBuffer[8];
	U32 tdw_FreeClusterNum;
	U32 uTemp;

	//backup DOS_SearchFreeCluster's global variable to temp
	memcpy(tdw_TempBuffer,gdw_ClusterBuffer,32); //U32 tdw_TempBuffer 8*4=32

	tc_ValidPoint = gc_ClusBufValidPoint;
	tc_ValidSize = gc_ClusBufValidSize;
	tdw_FreeClusterNum=gdw_FreeClusterNum[0];
	//confirm FAT copy end address
	if (tdw_HeadCluster > tdw_TailCluster)
	{
		tdw_CopyEndCluster = tdw_HeadCluster;	
	}
	else
	{
		tdw_CopyEndCluster = tdw_TailCluster;	
	}
	
	if (tdw_HeadCluster == tdw_TailCluster)
	{//only connect 0xffffffff to HeadCluster
		tc_ConnectMode = 0;//3
		tdw_CopyStartCluster = tdw_HeadCluster;//confirm start address of FAT Copy 
	}
	else if (DOS_GetNextCluster(tdw_HeadCluster,1) == 0)
	{//Create new file's FAT chain  
		tc_ConnectMode = 1;//0
		tdw_CopyStartCluster = tdw_HeadCluster;//confirm start address of FAT Copy				
	}
	else
	{//Connect to exist file's FAT chain
		tc_ConnectMode = 2;//2
		tdw_CopyStartCluster = 2;//confirm start address of FAT Copy
	}

	
	tdw_CurrentCluster = tdw_HeadCluster;
	
	
	DOS_MarkFATUpdate(gdw_DOS_Fat1Addr,0xaa);//mark FAT1 is updating now

	if (gc_DOS_FileSystemType == 0x00)
	{//FAT12
		U8	tc_SectorNum;
		U8	tc_OddCluster;
		
		tc_Dirty = 0;
		tdw_CurrentSector = ((tdw_CurrentCluster * 3) >> 1) >> 9;
		gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
		DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);//must read again
		while(!tc_ChainEndFlag)
		{
			//search free cluster initialize
			gc_ClusBufValidPoint = 0;
			gc_ClusBufValidSize = 1;
	
			if (tc_ConnectMode == 2)
			{//search free cluster from start
				/*gdw_FreeClusterNum[0]=0;
				while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1))) 
				{
					DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
				}*/
				gdw_ClusterBuffer[1] = tdw_TailCluster;
			}
			else if (tc_ConnectMode == 1)
			{
				//gdw_ClusterBuffer[0] = tdw_CurrentCluster;
				gdw_FreeClusterNum[0]=tdw_CurrentCluster;              //lizhn modify 040907
				while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1))) 
				{
					DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
				}
			}
	
			for (tc_ArrayNum = 1; tc_ArrayNum < 8; tc_ArrayNum ++)
			{
				tw_Offset = ((tdw_CurrentCluster * 3) >> 1) % 512;
				
				if (tdw_CurrentCluster == tdw_TailCluster)
				{//final a cluster chain	
					tdw_NextCluster = 0xffffffff;
				}
				else
				{//get next cluster chain value
					tdw_NextCluster = gdw_ClusterBuffer[tc_ArrayNum];
				}
					
				tc_SectorNum = tdw_CurrentSector % 3;//confirm current sector's situation
				tc_OddCluster = (U8)(tdw_CurrentCluster & 0x01);//odd or even
	
				
				//write next cluster number into previous cluster entry
				if (tw_Offset == 511)
				{//over edge state
					gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
					if ((tc_SectorNum == 0)||(tc_SectorNum == 1))
					{
						gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
						if(tc_SectorNum == 0)
						{
							gc_PlayRecordDataBuf[tw_Offset] &= 0x0f;
							gc_PlayRecordDataBuf[tw_Offset] |= (U8)((tdw_NextCluster & 0x0f) << 4);				
						}
						else
						{
							gc_PlayRecordDataBuf[tw_Offset] = (U8)tdw_NextCluster;		
						}
						uTemp= gdw_DOS_Fat1Addr + tdw_CurrentSector;
						tc_Status = DOS_AppendWrite_LogicSector(uTemp, 1);	
						tdw_CurrentSector++;
						//read next sector
						tc_Status = DOS_Read_LogicSector(uTemp+1, 1);

						if(tc_SectorNum == 0)
						{
							gc_PlayRecordDataBuf[0] = (U8)(tdw_NextCluster >> 4);					
						}
						else
						{
							gc_PlayRecordDataBuf[0] &= 0xf0;
							gc_PlayRecordDataBuf[0] |= (U8)((tdw_NextCluster >> 8) & 0x0f);
						
						}
					
					}
				}
				else
				{//normal state
	
					if (tc_OddCluster)
					{//odd cluster
						gc_PlayRecordDataBuf[tw_Offset] &= 0x0f;
						gc_PlayRecordDataBuf[tw_Offset] |= (U8)((tdw_NextCluster & 0x0f) << 4);
						gc_PlayRecordDataBuf[tw_Offset+1] = (U8)(tdw_NextCluster >> 4);
					}
					else
					{//even cluster
						gc_PlayRecordDataBuf[tw_Offset] = (U8)tdw_NextCluster;
						gc_PlayRecordDataBuf[tw_Offset+1] &= 0xf0;
						gc_PlayRecordDataBuf[tw_Offset+1] |= (U8)(0x0f & (tdw_NextCluster >> 8));
					}
				}
				tc_Dirty = 1;
	
				if (tdw_NextCluster == 0xffffffff)
				{
					tc_ChainEndFlag = 1;
					break;
				}
		
				tdw_NextSector = ((tdw_NextCluster * 3) >> 1) >> 9;//next sector 
				tdw_CurrentCluster = tdw_NextCluster;
		
				if (tdw_NextSector != tdw_CurrentSector)
				{
					tc_Dirty = 0;
					gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
					DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);
					tdw_CurrentSector = tdw_NextSector;
					DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_NextSector,1);
				}
			}//end for
		}//end while
		if (tc_Dirty)
		{
			gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
			DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector, 1);//write sector back
		}
	}//FAT12 end
	else
	{//FAT16&FAT32
		tc_Dirty = 0;

		tdw_CurrentSector = (tdw_CurrentCluster << gc_DOS_FileSystemType) >> 9;
		gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
		DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);//must read again
		//do connect chain
		
		while(!tc_ChainEndFlag)
		{	
			//search free cluster initialize
			gc_ClusBufValidPoint = 0;
			gc_ClusBufValidSize = 1;
	
			if (tc_ConnectMode == 2)
			{//search free cluster from start
				/*gdw_FreeClusterNum[0]=0;
				while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1)))
				{  
					DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
				}*/
				gdw_ClusterBuffer[1] = tdw_TailCluster;
			}
			else if (tc_ConnectMode == 1)
			{
				//gdw_ClusterBuffer[0] = tdw_CurrentCluster;
				gdw_FreeClusterNum[0]=tdw_CurrentCluster;
				while((gc_ClusBufValidSize < 8) && (gdw_FreeClusterNum[0] < (gdw_DOS_FatMaxCluster - 1))) 
				{
					DOS_SearchFreeCluster(0);//use gc_UserDataBuf[]
				}
			}
		
			for (tc_ArrayNum = 1; tc_ArrayNum < 8; tc_ArrayNum ++)
			{
				tw_Offset = (tdw_CurrentCluster << gc_DOS_FileSystemType) % 512;
				
				if (tdw_CurrentCluster == tdw_TailCluster)
				{//final a cluster chain	
					tdw_NextCluster = 0xffffffff;
				}
				else
				{//get next cluster chain value
					tdw_NextCluster = gdw_ClusterBuffer[tc_ArrayNum];
				}

				//write next cluster number into previous cluster entry
				gc_PlayRecordDataBuf[tw_Offset] = tdw_NextCluster; 
				gc_PlayRecordDataBuf[tw_Offset + 1] = tdw_NextCluster >> 8;
				if (gc_DOS_FileSystemType == 0x02)
				{//FAT32
					gc_PlayRecordDataBuf[tw_Offset + 2] = tdw_NextCluster >> 16; 
					gc_PlayRecordDataBuf[tw_Offset + 3] = tdw_NextCluster >> 24;
				}
				tc_Dirty = 1;
	
				if (tdw_NextCluster == 0xffffffff)
				{
					tc_ChainEndFlag = 1;
					break;
				}
		
				tdw_NextSector = (tdw_NextCluster << gc_DOS_FileSystemType) >> 9;//next sector 
				tdw_CurrentCluster = tdw_NextCluster;
		
				if (tdw_NextSector != tdw_CurrentSector)
				{
					tc_Dirty = 0;
					gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
					DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector,1);
					tdw_CurrentSector = tdw_NextSector;
					DOS_Read_LogicSector(gdw_DOS_Fat1Addr + tdw_NextSector,1);
				}
			}//end for
	
		}//end while
		
		if (tc_Dirty)
		{
			gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
			DOS_AppendWrite_LogicSector(gdw_DOS_Fat1Addr + tdw_CurrentSector, 1);//write sector back
		}
	}//FAT16&FAT32 end

	#if ((K_CARD_TYPE &0x01)== 0x01)//if nand flash is support	
	if (gc_CurrentCard < 2)
	{//close new block when FAT1 to FAT2 end
		SMC_LogicWriteEnd(0xffff);
		gc_NewBlockStatus = 0;
	}
	#endif

	DOS_MarkFATUpdate(gdw_DOS_Fat1Addr,0xf8);//mark updating is complete

	DOS_Copy_FATtoFAT(tdw_CopyStartCluster,tdw_CopyEndCluster, 1);//copy FAT1 to FAT2

	//restore DOS_SearchFreeCluster's global variable from temp
	memcpy(gdw_ClusterBuffer,tdw_TempBuffer,32);
	gc_ClusBufValidPoint = tc_ValidPoint;
	gc_ClusBufValidSize = tc_ValidSize;
	gdw_FreeClusterNum[0]=tdw_FreeClusterNum;
	return tc_Status;
}

//-------------------------------------------------------------------------------
U8 DOS_Copy_FATtoFAT(U32 tdw_HeadCluster, U32 tdw_TailCluster, bit tbt_fat1tofat2)
{
	U8	tc_Status = DOS_SUCCESS;
	U32 tdw_StartSector;
	U32 tdw_EndSector;
	U32 tdw_CopySize;
	U32 tdw_CopySourcetAddr;
	U32 tdw_CopyTargetAddr;
	U32 tdw_LoopCount;
	U32 tdw_MarkAddr;
	
	
	if (tdw_TailCluster >= gdw_DOS_FatMaxCluster)//exceed max cluster
		tdw_TailCluster = gdw_DOS_FatMaxCluster - 1;
	

	//calculate start and end address of copying
	if (gc_DOS_FileSystemType == 0)
	{//FAT12
		tdw_StartSector = (tdw_HeadCluster * 3 + 1) >> 1;
		tdw_StartSector >>= 9;
		tdw_EndSector = (tdw_TailCluster * 3 + 1) >> 1;
		tdw_EndSector >>= 9;
	}
	else
	{//FAT16&FAT32
		tdw_StartSector = (tdw_HeadCluster << gc_DOS_FileSystemType);
		tdw_StartSector >>= 9;
		tdw_EndSector = tdw_TailCluster << gc_DOS_FileSystemType;
		tdw_EndSector >>= 9;
	}
	
	tdw_CopySize = (tdw_EndSector - tdw_StartSector) + 1;

	//confirm the direction of the Copy operation
	if (tbt_fat1tofat2)
	{//FAT1 to FAT2
		tdw_CopySourcetAddr = gdw_DOS_Fat1Addr + tdw_StartSector;//copy source address
		tdw_CopyTargetAddr = gdw_DOS_Fat2Addr + tdw_StartSector;//copy target address
		tdw_MarkAddr = gdw_DOS_Fat2Addr;//mark updating address
	}
	else
	{//FAT2 to FAT1
		tdw_CopySourcetAddr = gdw_DOS_Fat2Addr + tdw_StartSector;
		tdw_CopyTargetAddr = gdw_DOS_Fat1Addr + tdw_StartSector;
		tdw_MarkAddr = gdw_DOS_Fat1Addr;
	}
	
	if (tdw_CopyTargetAddr != tdw_MarkAddr)
	{
		//mark updating flag 0xf8 ---> 0xaa
		DOS_MarkFATUpdate(tdw_MarkAddr,0xaa);
	}

	for (tdw_LoopCount = 0; tdw_LoopCount < tdw_CopySize; tdw_LoopCount ++)
	{
		gc_ReadWriteDataArea = 0;//select gc_PlayRecordDataBuf[]
		tc_Status = DOS_Read_LogicSector(tdw_CopySourcetAddr, 1);
		
		//not close new block
		if (tdw_LoopCount == 0 && tdw_CopyTargetAddr == tdw_MarkAddr)
		{//fisrt write sector is FAT1's start sector
			gc_PlayRecordDataBuf[0] = 0xaa;
		}
		tc_Status = DOS_AppendWrite_LogicSector(tdw_CopyTargetAddr, 1);

		tdw_CopySourcetAddr ++;//next sector
		tdw_CopyTargetAddr ++;//next sector
	}
	#if ((K_CARD_TYPE &0x01)== 0x01)//if nand flash is support		
	if (gc_CurrentCard < 2)
	{//close new block when FAT1 to FAT2 end
		SMC_LogicWriteEnd(0xffff);
		gc_NewBlockStatus = 0;
	}
	#endif
	
	DOS_MarkFATUpdate(tdw_MarkAddr,0xf8);//mark updating is complete
	

⌨️ 快捷键说明

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