f_fat.c

来自「基于arm9的,usb设备(u盘)的读写操作实现.」· C语言 代码 · 共 664 行 · 第 1/2 页

C
664
字号
/***************************************************************/
/*
 * F_FAT.c, 20070206, denny
 *
 * A Marconix Software Product
 * Copyright(c) Marconix Co., Ltd. 2007
 * All Rights Reserved. Reproduction, adaption, or
 * translation without prior written permission is
 * prohibited, except as allowed under the copyright laws.
 */
/***************************************************************/



#include "inc.h" 

#include "F_system.h"
#include "F_driver.h"
#include "F_FAT.h"

tHANDLE hFile;

u8 SectorBuffer[F_SectorSize] = {0};
u8 *prSectorBuf = SectorBuffer;
FAT_HANDLE CurrentHandle;
u8 FATBuffer[FAT_BUF_SIZE] = {0};
u8 *prFATBuffer = FATBuffer;
u8 g_lfnflag = 0;
c8 g_CurrentDir[20] = ":\\";
u16 g_longfilename[MAX_LFN_BUF] = {0};
c8 g_direntry[MAX_LAYER][MAX_DIR_LEN] = {0};



u32 BufferDataGet(u8 num, u8 *buffer)
{
	u8 i = 0;
	u32 u32data = 0;

	for(;i<num;i++)
		u32data += ((u32)(buffer[i]&0xFF))<<(8*i);
	return u32data;
}

void F_FAT_GetBPB(F_bpb710 *bpb, u8 *buffer)
{
	u8 i = 0, j=0;

	bpb->bpbBytesPerSec = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbSecPerClust = (u8)BufferDataGet(1, buffer);buffer+=1;
	bpb->bpbResSectors = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbFATs = (u8)BufferDataGet(1, buffer);buffer+=1;
	bpb->bpbRootDirEnts = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbSectors = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbMedia = (u8)BufferDataGet(1, buffer);buffer+=1;
	bpb->bpbFATsecs = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbSecPerTrack = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbHeads = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbHiddenSecs = BufferDataGet(4, buffer);buffer+=4;
	bpb->bpbHugeSectors = BufferDataGet(4, buffer);buffer+=4;
	bpb->bpbBigFATsecs = BufferDataGet(4, buffer);buffer+=4;
	bpb->bpbExtFlags = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbFSVers = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbRootClust = BufferDataGet(4, buffer);buffer+=4;
	bpb->bpbFSInfo = (u16)BufferDataGet(2, buffer);buffer+=2;
	bpb->bpbBackup = (u16)BufferDataGet(2, buffer);buffer+=2;
	for(;j<12;)
		bpb->bpbReserved[j++] = (u8)BufferDataGet(1, buffer);buffer+=1;
}

u8 F_FAT_Init( u8 Index)
{
	F_bpb710 bpb;
	F_partrecord PartInfo;
	u32 TotalSectors = 0;
	FAT_HANDLE *F_Handle = &CurrentHandle;

	PartInfo.prStartLBA = 0;

	if(F_ReadSector(hFile, PartInfo.prStartLBA, 1, prSectorBuf))
		return F_ERR_DRIVER_READ_FAILURE;
	if(prSectorBuf[0] == 0xE9 || (prSectorBuf[0] == 0xEB && prSectorBuf[2] == 0x90))//It's Boot Sector 
	{
//		Uart_Printf("Boot sector\n");
		if(prSectorBuf[510] != BOOTSIG0 || prSectorBuf[511] != BOOTSIG1 )
			return F_ERR_INVALID_BOOT_SECTOR;
	}
	else//It's MBR
	{
	//	Uart_Printf("MBR\n");
		if(prSectorBuf[510] != BOOTSIG0 || prSectorBuf[511] != BOOTSIG1 )
			return F_ERR_INVALID_MBR;

		PartInfo.prStartLBA = (u32)((((u32)prSectorBuf[0x1C9])<<24) + (((u32)prSectorBuf[0x1C8])<<16)+ (((u32)prSectorBuf[0x1C7])<<8) + (prSectorBuf[0x1C6]));

		if(F_ReadSector(hFile, PartInfo.prStartLBA, 1, prSectorBuf))
			return F_ERR_DRIVER_READ_FAILURE;

		if(prSectorBuf[510] != BOOTSIG0 || prSectorBuf[511] != BOOTSIG1 )
			return F_ERR_INVALID_BOOT_SECTOR;

	}
	F_FAT_GetBPB(&bpb, (u8 *)(((F_bootsector710*)prSectorBuf)->bsBPB));

	F_Handle->FirstDataSector = PartInfo.prStartLBA;

	if(bpb.bpbFATsecs)
	{
		F_Handle->FatSectors	= bpb.bpbFATsecs;
	}
	else
	{
		F_Handle->FatSectors	= bpb.bpbBigFATsecs;
	}
	F_Handle->RootDirSectors = ((bpb.bpbRootDirEnts * 32) + (bpb.bpbBytesPerSec -1))/bpb.bpbBytesPerSec;

	F_Handle->FirstDataSector	+= (bpb.bpbResSectors + bpb.bpbFATs * F_Handle->FatSectors) + F_Handle->RootDirSectors;

	if(bpb.bpbSectors)
	{
		TotalSectors = bpb.bpbSectors;
	}
	else
	{
		TotalSectors = bpb.bpbHugeSectors;
	}

	F_Handle->NumClusters = (TotalSectors - (bpb.bpbResSectors + (bpb.bpbFATs * F_Handle->FatSectors) + F_Handle->RootDirSectors))/ bpb.bpbSecPerClust;

	//FAT Type Determination by count of Clusters
	if(F_Handle->NumClusters < 4085)
	{
		F_Handle->PartType = PART_TYPE_FAT12;
	}
	else if(F_Handle->NumClusters < 65525)
	{
		F_Handle->PartType = PART_TYPE_FAT16;
	}
	else
	{
		F_Handle->PartType = PART_TYPE_FAT32;
	}
	
	F_Handle->SectorsPerCluster	= bpb.bpbSecPerClust;
	

	F_Handle->FirstFATSector		= bpb.bpbResSectors + PartInfo.prStartLBA;
	
	switch (F_Handle->PartType)
	{
		case PART_TYPE_FAT16:
			F_Handle->FirstDirCluster	= 0;//first legal cluster number for FAT16 , the First Data Cluster is 2 , the Root Entry is fixed  
			break;
		case PART_TYPE_FAT32:
			F_Handle->FirstDirCluster = bpb.bpbRootClust;//Usually 2 but not required to be 2 , it should be 2 unless it's marked bad.
			break;
		default:
			return F_ERR_UNSUPPORTED_PARTITION_TYPE;
	}

	if (F_Handle->PartType == PART_TYPE_FAT32)
	{
		F_Handle->FirstFAT2Sector=F_Handle->FirstFATSector+bpb.bpbBigFATsecs;
	}
	else
	{
		F_Handle->FirstFAT2Sector=F_Handle->FirstFATSector+bpb.bpbFATsecs;
	}

	F_Handle->BytesPerSector = bpb.bpbBytesPerSec;
	F_Handle->currentDirCluster= F_Handle->FirstDirCluster;
/*
	Uart_Printf("F_Handle->PartType = %d\n",F_Handle->PartType);
	Uart_Printf("F_Handle->BytesPerSector = %d\n",F_Handle->BytesPerSector);
	Uart_Printf("F_Handle->FirstDataSector = %d\n",F_Handle->FirstDataSector);
	Uart_Printf("F_Handle->SectorsPerCluster = %d\n",F_Handle->SectorsPerCluster);
	Uart_Printf("F_Handle->FirstFATSector = %d\n",F_Handle->FirstFATSector);
	Uart_Printf("F_Handle->FirstDirCluster = %d\n",F_Handle->FirstDirCluster);
	Uart_Printf("F_Handle->FatSectors = %d\n",F_Handle->FatSectors);
	Uart_Printf("F_Handle->NumClusters = %d\n",F_Handle->NumClusters);
	Uart_Printf("F_Handle->currentDirCluster = %d\n",F_Handle->currentDirCluster);
	*/
		
	return ERR_NONE;
	
}

u8 F_FAT_FolderChange(FAT_HANDLE *pHandle, c8 *FolderName)
{
	F_BrowsingCursor cursor;
	F_direntry de;
	F_FolderInfo folderInfo;
	u16 unicode[MAX_LFN_BUF] = {0};
	c8 tmpname[MAX_LFN_BUF] = {0};
	c8 tmpname1[MAX_LFN_BUF] = {0};


	if(!strcmp(FolderName, "\\\\"))
	{
		F_FAT_DirInit(pHandle);
	}
	else
	{
		strcpy(tmpname, FolderName);
		strupr(tmpname);
		g_lfnflag = 0;
		memset((u8 *)g_longfilename, 0, MAX_LFN_BUF);
		F_FAT_BrowsingReset(pHandle, &cursor);
		for(;F_FAT_GetNextDirEntry(pHandle, &de,  &cursor, MAX_LFN_BUF, g_longfilename) == 0;)
		{
			if(de.deAttributes == ATTR_DIRECTORY)
			{
				if(g_lfnflag)
				{
					memcpy((u8 *)unicode, (u8 *)g_longfilename, MAX_LFN_BUF);
					MX_UniStrToGB2312Str(unicode, folderInfo.folderINF_Name);
					g_lfnflag = 0;

					strcpy(tmpname1, folderInfo.folderINF_Name);
					strupr(tmpname1);
					if(!strcmp(tmpname, tmpname1))
					{
						folderInfo.folderINF_start_cluster = de.deStartCluster + (de.deHighClust<<16);
						//printf("(LFN)File Name: %s,\tStart Cluster:%d,\n", folderInfo.folderINF_Name, folderInfo.folderINF_start_cluster);

						F_FAT_DirSet(folderInfo.folderINF_Name);
						pHandle->currentDirCluster = folderInfo.folderINF_start_cluster;
						return ERR_NONE;
					}
				}
				else
				{
					F_FAT_DirEntryToSFN(&de, folderInfo.folderINF_Name, 13);
					strcpy(tmpname1, folderInfo.folderINF_Name);
					strupr(tmpname1);
					if(!strcmp(tmpname, tmpname1))
					{
						folderInfo.folderINF_start_cluster = de.deStartCluster + (de.deHighClust<<16);
						//printf("(SFN) File Name: %s,\tStart Cluster:%d,\n", folderInfo.folderINF_Name, folderInfo.folderINF_start_cluster);
						F_FAT_DirSet(folderInfo.folderINF_Name);
						pHandle->currentDirCluster = folderInfo.folderINF_start_cluster;
						return ERR_NONE;
					}
				}
				
			}
			g_lfnflag = 0;
			memset((u8 *)g_longfilename, 0, MAX_LFN_BUF);
		}
	}
	return F_ERR_FILE_NOT_EXIST;
}

void F_FAT_DirSet(c8 *dirname)
{
	u32 dirlen = strlen(dirname);
	u32 latestlen = strlen(g_CurrentDir);
	u8 i=0,j=0;
	if(!strcmp(dirname, ".."))
	{
		if(latestlen <= 3)
			return ;
		else
		{
			for(i = (latestlen-2);i>2;i--)
			{
				if(g_CurrentDir[i] != '\\')
					g_CurrentDir[i] = '\0';
				else
					break;
			}
		}
	}
	else
	{
		for(i=latestlen;i<latestlen+dirlen;i++)
			g_CurrentDir[i] = dirname[i-latestlen];
		g_CurrentDir[i] = '\\';g_CurrentDir[i+1] = '\0';
	}
}


FAT_HANDLE * F_FAT_GetCurrentFolder(void)
{
	FAT_HANDLE *Cur;

	Cur = &CurrentHandle;
	return (Cur);
}

u32 F_FAT_ClusterToSector(FAT_HANDLE *pHandle,u32 Cluster)
{
	if (pHandle->PartType == PART_TYPE_FAT32)
	{
		if (Cluster == 0)
			Cluster=pHandle->FirstDirCluster;
	}
	else
	{
		if (Cluster == 0)
			return pHandle->FirstDataSector - pHandle->RootDirSectors;
	}
	return ((Cluster-2) * pHandle->SectorsPerCluster) + pHandle->FirstDataSector;
}

u32 F_FAT_SectorToCluster(FAT_HANDLE *pHandle,u32 Sector)
{
	if(Sector >= pHandle->FirstDataSector)
		return (((Sector - pHandle->FirstDataSector) / pHandle->SectorsPerCluster) + 2);
	else//FAT16 Root Folder 
		return 0;
}

u8 F_FAT_GetNextDirEntry(FAT_HANDLE *pHandle, F_direntry *pde, F_BrowsingCursor *Cursor, u16 LFNlen, u16 *LFNBuf)
{
	u8 Error = ERR_NONE, i = 0;
	u32 u32currnetsector = 0, nextCluster = 0, nextSector = 0;
	F_direntry *de;
	
	for(;;Cursor->SectorOffset++)
	{
		if((Cursor->SectorOffset%pHandle->SectorsPerCluster == 0)&&(Cursor->DirEntryIndex == 0))
		{
			if(Cursor->SectorOffset == 0 && Cursor->CurrentSectorAddr == F_FAT_ClusterToSector(pHandle, pHandle->currentDirCluster))
			{
				if(F_ReadSector(hFile, Cursor->CurrentSectorAddr, 1, prSectorBuf))
					return F_ERR_DRIVER_READ_FAILURE;
				de = (F_direntry *)prSectorBuf;
			}			
			else
			{
				Cursor->SectorOffset = 0;

⌨️ 快捷键说明

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