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

📄 fat.h

📁 用SL811做USB主机的源码
💻 H
📖 第 1 页 / 共 3 页
字号:
#ifndef __Fat_h__
#define __Fat_h__

// 以下默认每扇区512字节
// sizeof(FILE_INFO) = 32

typedef struct 
{
  uint16   SectorBytes; 		//每扇区字节数 
  uint8    SectorsPerCluster; 	//每簇扇区数 
  uint16   ReservedSectors; 	//保留扇区数 
  uint8    NbrFat; 				//FAT的个数 
  uint16   RootEntry; 			//根目录项数 
  uint16   TotalSectors; 		//分区总扇区数(分区小于32M时) 
  uint8    Media; 				//分区介质标识 
  uint16   SectorsPerFAT; 		//每个FAT占的扇区数 
  uint16   SectorsPerTrack; 	//每道扇区数 
  uint16   Heads; 				//磁头数 
  uint32   HiddenSectors; 		//隐含扇区数 
  uint32   BigTotalSectors; 	//分区总扇区数(分区大于32M时) 
  uint32   FATSz32;			    //FAT32中每个FAT占的扇区数
  uint16   ExtFlags;
  uint16   FSVer;
  uint32   RootClus;
}BPB_FAT16;

typedef struct
{
  uint8	   BootFlag; 			//启动标志 
  uint8    StartCHS[3]; 		//分区开始的柱面、磁头、扇区 
  uint8	   SystemID; 			//分区类型 
  uint8	   EndCHS[3]; 			//分区结束的柱面、磁头、扇区 
  uint32   RelativeSectors; 	//分区相对扇区数,指分区相对于记录该分区的分区表的扇区位置之差 
  uint32   TotalSectors;		//分区总扇区数 
}PARTITION_TABLE;

typedef struct
{
  uint8	   FileName[8]; 		//文件正名 
  uint8    FileExtName[3]; 		//文件扩展名
  uint8	   Attribute; 			//文件属性
  uint8	   Nouse0[2]; 			//仅长文件名目录项用,用来存储其对应的短文件名目录项的文件名字节校验和等。 
  uint16   FileTime; 			//16位二进制的文件建立时间,其中的高5位为小时,次6位为分钟。 
  uint16   FileDate;			//16位二进制的文件建立日期,其中的高7位为相对于1980年的年份值,次4位为月份,后5位为月内日期。
  uint16   FileNewAccessDate;   //16位二进制的文件访问日期,其中的高7位为相对于1980年的年份值,次4位为月份,后5位为月内日期。
  uint16   High16;			    //起始簇号的高16位。	
  uint16   FileNewModifyTime;   //16位二进制的文件最新修改时间,其中的高5位为小时,次6位为分钟,后5位的二倍为秒数。
  uint16   FileNewModifyDate;   //16位二进制的文件最新修改日期		
  uint16   Low16;			    //起始簇号的低16位。 
  uint32   FileLength; 			//32位的文件字节长度。																	 
}FILE_INFO;

typedef struct
{
  uint32	  StartClusterNum;			// 簇链指针
  uint32	  StartAddress;				// 当前簇的起始扇区地址
  uint8		  NowSectorInCluster;		// 当前簇中的第几扇区
  uint16 	  NowDataInSector;			// 当前扇区的数据指针
}FILE_INFO_RW;

PARTITION_TABLE First_Partition;
BPB_FAT16		Bpb_Fat16;
FILE_INFO		File_Information;

uint8  FAT_ID = 0x06;
uint32 FAT1Start;
uint32 FAT2Start;
uint32 DIRStart;
uint32 DIREnd;
uint32 SecondClusterStart;
uint16 FAT1[259];
uint8  FAT1num;

#define MAXFILENUMREAD	  1
#define MAXFILENUMWRITE	  1
#define MAXFILENUM 		  MAXFILENUMREAD+MAXFILENUMWRITE
#define MAXFILECHAINLEN   2048
// 能处理文件最大大小为MAXFILECHAINLEN*SectorsPerCluster*SectorBytes

uint8			RWFileStatus[MAXFILENUM];
FILE_INFO	    RWFileInfo[MAXFILENUM];		
uint32			RWFileClusterChain[MAXFILENUM][MAXFILECHAINLEN];  
uint8			RWFileTempBuffer[MAXFILENUMWRITE][512];

FILE_INFO_RW	FileInfoRW[MAXFILENUM]; 	  

// 文件号最大到MAX(0xFE,MAXFILENUM)
uint8 FindUnusedFileNum(uint8 sel)
{
 uint8 i;
 
 if( sel == 0)
 {
   for(i=0;i<MAXFILENUMWRITE;i++) if(RWFileStatus[i] == 0) return i;
 }
 else if( sel == 1 )
 {
   for(i=MAXFILENUMWRITE;i<MAXFILENUM;i++) if(RWFileStatus[i] == 0) return i; 
 }
 
 return 0xFF;
}

uint8 DiscardFile(uint8 filenum)
{
 if(filenum < MAXFILENUM) RWFileStatus[filenum] = 0;
 else return 0x10;
 
 return 0x00;
}

void DiscardAllFiles(void)
{
 uint8 i;
 for(i=0;i<MAXFILENUM;i++)  RWFileStatus[i]= 0;
}


uint8 Fat_Initial(void)
{
 uint16 i,j;
 
 UFI_Read10(0);
 if(ReadBlockData[0] == 0xfa && ReadBlockData[1] == 0x33)
 {
  for(i = 0; i< 16; i++)  ((uint8*)&First_Partition)[i] = ReadBlockData[446+i]; // 0x01BE
  if(First_Partition.SystemID != 0x06 && First_Partition.SystemID != 0x04 && First_Partition.SystemID != 0x01 && First_Partition.SystemID != 0x0B) 
  { 
    puts("Not Fat16 or FAT12 or FAT32 File system1!\n");
    return 0x10;
  } 
  FAT_ID = First_Partition.SystemID;
 }
 else if(ReadBlockData[0] == 0x33 && ReadBlockData[1] == 0xc0)
 {
  for(i = 0; i< 16; i++)  ((uint8*)&First_Partition)[i] = ReadBlockData[446+i]; // 0x01BE
  if(First_Partition.SystemID != 0x06 && First_Partition.SystemID != 0x04 && First_Partition.SystemID != 0x01 && First_Partition.SystemID != 0x0B) 
  { 
    puts("Not Fat16 or FAT12 or FAT32 File system2!\n");
    return 0x10;
  } 
  FAT_ID = First_Partition.SystemID;
 }  
 else
 {
  First_Partition.RelativeSectors = 0;   	// First_Partition.RelativeSectors 不一定可用,所以强制赋0
  if(ReadBlockData[0x39] == 0x31)
  {
    if(ReadBlockData[0x3A] == 0x32) FAT_ID = 0x01;
    else if(ReadBlockData[0x3A] == 0x36) FAT_ID = 0x06;
	else
	{
     puts("Not Fat16 or FAT12 or FAT32 File system3!\n");
     return 0x09; 	
	}
  }
  else if(ReadBlockData[0x39] == 0x33 && ReadBlockData[0x3a] == 0x32)
  {
    FAT_ID = 0x0B;
  }
  else
  {
    puts("Not Fat16 or FAT12 or FAT32 File system4!\n");
    return 0x10;    
  }
 }
 printf("FAT_ID is %x\n",FAT_ID);

 UFI_Read10(First_Partition.RelativeSectors);
 if( ReadBlockData[0]!=0xEB && ReadBlockData[0]!=0xE9) 
 {
  printf("Error sector!");
  return 0x11;
 }
 for(i = 0; i< 37; i++)  ((uint8*)&Bpb_Fat16)[i] = ReadBlockData[11+i];		   // 0x0B

 if( Bpb_Fat16.SectorBytes != 512)//每个扇区为512字节
 {
    puts("Bytes per sector is not 512! Not supportted!\n");
    return 0x12;  
 }
 
 if( FAT_ID == 0x0B )
 {
  FAT1Start = First_Partition.RelativeSectors+Bpb_Fat16.ReservedSectors;
  FAT2Start = FAT1Start + Bpb_Fat16.FATSz32;
  DIRStart = FAT2Start + Bpb_Fat16.FATSz32;
  DIREnd = DIRStart + Bpb_Fat16.RootClus*Bpb_Fat16.SectorsPerCluster - 1; 
  SecondClusterStart = DIRStart;  
 }
 else
 {
  FAT1Start = First_Partition.RelativeSectors+Bpb_Fat16.ReservedSectors;
  FAT2Start = FAT1Start + Bpb_Fat16.SectorsPerFAT;
  DIRStart = FAT2Start + Bpb_Fat16.SectorsPerFAT;
  SecondClusterStart = DIRStart + (Bpb_Fat16.RootEntry/Bpb_Fat16.SectorBytes)*32; 
  DIREnd = SecondClusterStart - 1;
 }
 
 printf("FAT1Start = %x\n",FAT1Start);
 printf("FAT2Start = %x\n",FAT2Start); 
 printf("DIRStart = %x\n",DIRStart); 
 printf("DIREnd = %x\n",DIREnd);  
 printf("SecondClusterStart = %x\n",SecondClusterStart); 
 
 UFI_Read10(FAT1Start);  
 if(ReadBlockData[0] != 0xF8)
 {
  puts("Wrong FAT!");
  return 0x13;
 }
 //puts("Good!");while(1);
 for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i];
 FAT1num = 0;
 
 DiscardAllFiles();
 for(i=0;i<MAXFILENUM;i++)
 {
  	for(j=0;j<MAXFILECHAINLEN;j++) RWFileClusterChain[i][j] = 0;
 }
 return 0;
}

uint8 Printf_Directory(void)
{
 uint8 i,j,k;
 uint32 StartAddress;
 
 UFI_Read10(DIRStart);
 Printf_ReadBlockDatabuffer();
 for(i=0;i<16;i++)
 {
   puts("File:");   
   for(j=0;j<32;j++) ((uint8*)&File_Information)[j] = ReadBlockData[i*32 + j];
   if(File_Information.FileName[0] == 0) break;
   if(File_Information.FileName[0] == 0xE5) continue;   
   if(File_Information.FileName[0] == 0x05) File_Information.FileName[0] = 0xE5;
   for(k=0;k<8;k++) putchar(File_Information.FileName[k]);
   putchar('.');
   for(k=0;k<3;k++) putchar(File_Information.FileExtName[k]);   
   printf("  Start@ ");
   StartAddress = ((File_Information.High16*65536 + File_Information.Low16)-2)*Bpb_Fat16.SectorsPerCluster+SecondClusterStart;
   printf("0x%lx  ",StartAddress);
   printf("Length: 0x%lx bytes\n",File_Information.FileLength);
 }
 return 0;
}

uint16 NextCluster(uint16 StartCluster)
{
 uint16 temp;
 uint16 i;
 uint8  tag;
 uint16 number;
 uint16 NextCluster;
 
 if(FAT_ID == 0x0B)
 {
	 temp = StartCluster/128; 
	 if( (temp+FAT1Start) >= FAT2Start) return 0x20;
	 if( temp != FAT1num) 
	 {
	   UFI_Read10(FAT1Start + temp);  
	   FAT1num = temp;
	   for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i];   
	 }
	 
	 temp = StartCluster%128; 
	 return ((uint32*)&FAT1)[temp];	 
 }
 else if(FAT_ID == 0x01)
 {
	 number = StartCluster*3>>1;
	 if(number<<1 == StartCluster*3) tag = 0;
	 else tag = 1;
	 temp = number>>9;
	 if( (temp+FAT1Start) >= FAT2Start) return 0x20;
	 if( temp != FAT1num)  
	 {
	   UFI_Read10(FAT1Start + temp);  
	   FAT1num = temp;
	   for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i];  	 	
	 }// end of if( temp != FAT1num) 
	 if(tag == 0)
	 {
	 	if(number%512 == 511)
	 	{
	 		NextCluster = ((uint8*)&FAT1)[511];
	 	    UFI_Read10(FAT1Start + temp + 1);  
	        FAT1num = temp+1;
	        for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i]; 	
	        NextCluster += (((uint8*)&FAT1)[0] & 0x0F)<<8;	
	 	}
	 	else
	 	{
	 		NextCluster = ((uint8*)&FAT1)[number%512] + (((uint8*)&FAT1)[number%512+1]& 0x0F)<<8;
	 	}
	 }
	 else
	 {
	 	if(number%512 == 511)
	 	{
	 		NextCluster = (((uint8*)&FAT1)[511]& 0xF0)>>4;
	 	    UFI_Read10(FAT1Start + temp + 1);  
	        FAT1num = temp+1;
	        for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i]; 	
	        NextCluster += (((uint8*)&FAT1)[0])<<4;	
	 	}
	 	else
	 	{
	 		NextCluster = (((uint8*)&FAT1)[number%512]& 0xF0)>>4 + (((uint8*)&FAT1)[number%512+1])<<4;
	 	}	 	
	 } // end of if(tag == 0)
	 
	 return NextCluster;
 }
 else
 {
	 temp = StartCluster/256; 
	 if( (temp+FAT1Start) >= FAT2Start) return 0x20;
	 if( temp != FAT1num) 
	 {
	   UFI_Read10(FAT1Start + temp);  
	   FAT1num = temp;
	   for(i=0;i<512;i++) ((uint8*)&FAT1)[i] = ReadBlockData[i];   
	 }
	 
	 temp = StartCluster%256; 
	 return FAT1[temp];	
 } // end of if(FAT_ID == 0x01)
}


void List_Fat(void)
{
 unsigned int i;
 
  UFI_Read10(DIRStart);
  for(i=0;i<512;i++)
  {
   Fat_data[i] = ReadBlockData[i];//Fat
  } 
}


uint8 ReadFile4Print(uint8* FileName)
{
 uint8 i,j,k;
 uint32 StartCluster,StartAddress;
 uint32 SectorAddress;
 uint16 len;
 
 for(SectorAddress=DIRStart;SectorAddress <=DIREnd ;SectorAddress++)
 {
  UFI_Read10(SectorAddress);
  for(i=0;i<16;i++)
  {
   for(j=0;j<32;j++) ((uint8*)&File_Information)[j] = ReadBlockData[i*32 + j];//Fat
   if(File_Information.FileName[0] == 0) return 0x10;
   if(File_Information.FileName[0] == 0xE5) continue; //已删除 
   if(File_Information.FileName[0] == 0x2E) continue; //目录信息
   if(File_Information.FileName[0] == 0x05) File_Information.FileName[0] = 0xE5;  //本身为 e5h    
   for(k=0;k<11;k++) if(FileName[k] != File_Information.FileName[k]) break;
   if(k==11)
   {
   	StartCluster = File_Information.High16*65536 + File_Information.Low16;
   	StartAddress = (StartCluster-2)*Bpb_Fat16.SectorsPerCluster+SecondClusterStart;
	//goto PrintFile_;
   }
  } 
 }  
 return 0x20;
 
PrintFile_:
//
  UFI_Read10(StartAddress);  
  for(len = 0; len < File_Information.FileLength; len++)
  {
   	putchar(ReadBlockData[len]);
	if(len == 511)
	{
	  StartCluster = NextCluster(StartCluster);
	  if( FAT_ID == 0x0B)
	  {
	   if(StartCluster >= 0xFFFFFFF0) return 0x30;	  
	  }
	  else if( FAT_ID == 0x01)
	  {
	   if(StartCluster >= 0xFF0) return 0x31;
	  }
	  else
	  {
	   if(StartCluster >= 0xFFF0) return 0x32;	  
	  }	  
	  UFI_Read10((StartCluster-2)*Bpb_Fat16.SectorsPerCluster+SecondClusterStart);
	  len = 0;
	  File_Information.FileLength -= 512;
	}
  }
  return 0;
}

// if file exist return 0x01 else return 0
uint8 DetectFile(uint8* FileName)
{
 uint8 i,j,k,filenum;
 uint32 StartCluster,StartAddress;
 uint32 SectorAddress;
 uint16 len;
 
 for(SectorAddress=DIRStart;SectorAddress <= DIREnd;SectorAddress++)
 {
  UFI_Read10(SectorAddress);
  for(i=0;i<16;i++)
  {
   for(j=0;j<32;j++) ((uint8*)&File_Information)[j] = ReadBlockData[i*32 + j];
   if(File_Information.FileName[0] == 0) return 0;
   if(File_Information.FileName[0] == 0xE5) continue;   
   if(File_Information.FileName[0] == 0x2E) continue;
   if(File_Information.Attribute & 0x18 ) continue;		//是目录或者卷标            
   if(File_Information.FileName[0] == 0x05) File_Information.FileName[0] = 0xE5;    
   for(k=0;k<11;k++) if(FileName[k] != File_Information.FileName[k]) break;
   if(k==11) return 0x01;
  }  // end of for(i=0;i<16;i++)
 }  // end of for(SectorAddress=DIRStart;SectorAddress <= DIREnd;SectorAddress++)
 return 0;
}


// if success return filenum else return 0xFF = failure
uint8 OpenFile(uint8* FileName)
{
 uint8 i,j,k,filenum;
 uint32 StartCluster,StartAddress;
 uint32 SectorAddress;
 uint16 len;

⌨️ 快捷键说明

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