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

📄 fat.c

📁 嵌入式FAT文件系统源码免费下载
💻 C
📖 第 1 页 / 共 5 页
字号:
===============================================================================*/
static void BPB_INIT_2(void)
{ //计算根目录占用的扇区数 
  CORE.RootDirSectors = (BPB.boot_entries * 32 + (BPB.bytes_per_sector - 1)) / BPB.bytes_per_sector;                             
  //计算数据区的起始扇区                            
  CORE.FirstDataSector = CORE.relative_sector + BPB.reserved_sector + BPB.sectors_per_FAT
                               * BPB.numbers_of_FAT + CORE.RootDirSectors;
  //计算根目录的起始扇区
  CORE.FirstRootDirSecNum = CORE.relative_sector + BPB.reserved_sector+ BPB.sectors_per_FAT
                               * BPB.numbers_of_FAT;
  //计算数据区占用扇区数
  CORE.DataSec = CORE.total_sector - BPB.reserved_sector - CORE.RootDirSectors
                 - BPB.sectors_per_FAT * BPB.numbers_of_FAT;
  //计算数据区对应的簇数
  CORE.CountofClusters = CORE.DataSec / BPB.sector_per_cluster;
  //计算FAT1,FAT2的起始扇区
  CORE.FirstSectorofFAT1 = CORE.relative_sector + BPB.reserved_sector;
  CORE.FirstSectorofFAT2 = CORE.relative_sector + BPB.reserved_sector + BPB.sectors_per_FAT;
}
/*===============================================================================
函数
Read Partition PBP
入口:Partition ID
出口:无
===============================================================================*/ 
static u8 Read_partition_PBP(u8 partition_ID)
{  
  u8 *ptr1,*ptr2; 
  u16 i; 
  u8 buf[512];  
   if ((CORE.PartitionID - 'C') ==  partition_ID) 
    { 
	  //指定的BPB已经在缓冲中,直接返回
      return(SUCC);
    } 
   //读取MBR,即扇区0
   read_flash_sector(buf,0); //read MBR 
   if ( buf[0x1be] == 0x00 || buf[0x1be] == 0x80) // check boot indicator 00 or 0x80
   {
   
   }
   else
   {
	   CORE.relative_sector = 0; 
       CORE.total_sector =  *((u32*) (buf+32));//保存分区容量
       CORE.system_id = buf[0x1c2]; //保存分区类型 0C-FAT32,06-FAT16 ect..
       CORE.PartitionID= 'C' + partition_ID; //从C开始到Z结束 
	   //保存BPB数据
	   if ( buf[510] == 0x55 && buf[511] == 0xaa)
       {
        //每扇区字节数
        BPB.bytes_per_sector = buf[0xb] + buf[0xc] * 256;
        
        //每簇扇区数
        BPB.sector_per_cluster = buf[0xd];
        //保留扇区数
        BPB.reserved_sector = buf[14] + buf[15] * 256;

        //FAT副本数
        BPB.numbers_of_FAT = buf[16];
        //根目录项数,供FAT12/16使用
        BPB.boot_entries = buf[17] + buf[18] * 256;
        //This field is the old 16-bit total count of sectors on the volume.
        BPB.TotSec16 = buf[19] + buf[20] * 256;
        BPB.TotSec16 = 0xffff;
        //媒体描述符
        BPB.media_descriptor = buf[21];
        //每个FAT表占用的扇区数,供FAT12/16使用
        BPB.sectors_per_FAT =  buf[22] + buf[23] * 256;
        CORE.system_id = 0x6; //保存分区类型 0C-FAT32,06-FAT16 ect..
        BPB_INIT_2();
        return(SUCC);
       } 
	 }
    
  return(FAIL);
}  

/*===============================================================================
函数
从路径中读一个entry
入口:
出口:SUCC,FAIL
===============================================================================*/
static u8 SplitNameFromPath(u8 *Path,u8 *Return_Entry_Name,u8 *FileExtension,u8 *RemovedCharsFromPath)
{  
  u8 i,flag,j;
  flag = FILE_NAME;
  *RemovedCharsFromPath = 0; 
  CORE.CurPathType = DirectoryPath; 
  i = 0; 
  j = 0;
  do{           
     if( ( * Path) != 0 && ( * Path ) != '\\') //Path分离得到Entry name and file extension 
       { 
        (*RemovedCharsFromPath)++; 
        //分离ENTRY NAME
		if( flag == FILE_NAME)
         {            
          if(*Path == '.')
             {//遇到".",则开始分离file extension 
              flag  = FILE_EXTENSION;
              Path ++; 
             }  
          else
            {
             Return_Entry_Name[i] =  *Path;
             i++; 
             Path++;
            }
          }
        else if( flag  == FILE_EXTENSION)
         {//分离file extension
          if( j >= 3 )
            return(FAIL);
          FileExtension[j] =  *Path;
          j++;
          Path++;
         } 
      }
    else
      {//分离结束,检查是否是最后的一个ENTRY?
       if(!( * Path))
        {
          if(CORE.FullPathType == FilePath)
		  {
		  CORE.CurPathType = FilePath;
		  }
          FileExtension[j] = 0;
          Return_Entry_Name[i] = 0;
		  //最后一个ENTRY,返回LastSplitedNameofPath
          return(LastSplitedNameofPath);  
        } 
       (*RemovedCharsFromPath)++; 
       FileExtension[j] = 0;
       Return_Entry_Name[i] = 0;	   
       break;
      }
 }while(1); 
 return(SUCC);
} 
/*===============================================================================
函数
Directory Entry的位置+32,转向下一个ENTRY 
入口:无
出口:SUCC,FAIL
===============================================================================*/             
static u8 CORE_offset_add_32(u8 *buf)
{ //位置+32
  CORE.offset += 32;
  if (CORE.offset >= 512)
  {
  //位置越过一个扇区
  if (CORE.DirectoryType == RootDirectory)
  {     //针对根目录的处理
        if (CORE.SectorNum < ( CORE.RootDirSectors +  CORE.FirstRootDirSecNum))
         {
           CORE.SectorNum++;
           CORE.offset = 0; 
           read_flash_sector(buf,CORE.SectorNum);
		   if(buf[CORE.offset] == 0 && buf[CORE.offset+1] == 0)  //End of the directory
		     return(FAIL);//已没有ENTRY,返回FAIL
           return(SUCC);
         }
        else
           return(FAIL);
     }
    else  
     {
        if( (CORE.SectorNum - FirstSectorofCluster(CORE.ClusterNum) + 1) >= BPB.sector_per_cluster)
		{ //位置越过一个簇, 取下一簇,继续处理
           CORE.ClusterNum = Get_Next_Cluster_From_Current_Cluster(CORE.ClusterNum);
           if( CORE.ClusterNum >= 2 && CORE.ClusterNum <= 0xfff7)
            {
               CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum); 
               CORE.offset = 0;
               read_flash_sector(buf,CORE.SectorNum);
			   if(buf[CORE.offset] == 0 && buf[CORE.offset+1] == 0)  //End of the directory
                   return(FAIL);//已没有ENTRY,返回FAIL
               return(SUCC);
            }
           else
			 return(FAIL);
         }
        else
         {
            CORE.SectorNum++; 
            CORE.offset = 0;
            read_flash_sector(buf,CORE.SectorNum);
			if(buf[CORE.offset] == 0 && buf[CORE.offset+1] == 0)  //End of the directory
                return(FAIL);//已没有ENTRY,返回FAIL
            return(SUCC);
         }
     }
  }
  if(buf[CORE.offset] == 0 && buf[CORE.offset+1] == 0)  //End of the directory
       return(FAIL);//已没有ENTRY,返回FAIL
  return(SUCC);
}
/*===============================================================================
函数
从目录读取短文件名
入口:EntryName-返回文件名,Extension=返回扩展名
出口:SUCC,FAIL
===============================================================================*/ 
static u8 GetEntryWith8_3Name(u8 *buf,u8* EntryName,u8 *Extension)
{
  u8 j;
  struct Directory_Entry_  *Directory_Entry_Local;  
  u8 *pointer;
  pointer = buf;
  Directory_Entry_Local = (struct Directory_Entry_ *) (pointer + CORE.offset);
  //从DIRECTORY 中读取EntryName  
  for(j = 0;j < 8;j++)
   {
    if(Directory_Entry_Local->filename[j] == 0x20)
      break;
    EntryName[j] = Directory_Entry_Local->filename[j];
   }   
  EntryName[j] = 0; 
  //从DIRECTORY 中读取Extension
  for(j = 0;j < 3;j++)
   {  
    if(Directory_Entry_Local->file_extention[j] == 0x20)
        break;
    Extension[j] = Directory_Entry_Local->file_extention[j]; 
   }
  Extension[j] = 0;

  if(CORE.FullPathType == FilePath && CORE.CurPathType == FilePath)
     CORE.FileSize = *(u32*)Directory_Entry_Local->file_length;//保存文件长度
  Directory_Entry_Local->file_length[0] = 0;
  Directory_Entry_Local->file_length[0] = 0;
  //保存文件首簇号
  CORE.ClusterOfDirectoryEntry = (Directory_Entry_Local->first_cluster_number_low2bytes[0]) + 
	  (Directory_Entry_Local->first_cluster_number_low2bytes[1]) * 256;
  CORE.PreEntrySectorNum = CORE.SectorNum;
  CORE.PreEntryoffset = CORE.offset;
  CORE_offset_add_32(buf);//Directory Entry的位置+32 
  return(SUCC);
}
/*===============================================================================
函数
从目录读取长文件名
入口:longFileName-返回文件名,Extension=返回扩展名
出口:SUCC,FAIL
===============================================================================*/ 
static u8 GetEntryWithLongFileName(u8 *buf,u8* longFileName,u8 *Extension)
{
 u8 j,FileNameOffset;
                   
 u8 flag,k,i;
 u16 len;
 struct LongNameDirectoryEntry *LongNameDirectoryEntry_Local;
 *Extension = 0;

 FileNameOffset = 242;
 LongNameDirectoryEntry_Local = (struct LongNameDirectoryEntry *) (buf + CORE.offset);
 do{
	 k = FileNameOffset;
	 //读取longNameDirectoryEntry中的前5个字节
     for(j = 1;j < 10;j+=2)
      {        
       if (LongNameDirectoryEntry_Local->dir_lname1[j] == 0)
          break; //遇0结束退出  
       longFileName[k] = LongNameDirectoryEntry_Local->dir_lname1[j];
       k ++;                 
      } 
	 longFileName[k] = 0;
       if(j >= 10)
         { //读取longNameDirectoryEntry中的第二6个字节
           for(j = 0;j < 12;j += 2)
            {  
              if (LongNameDirectoryEntry_Local->dir_lname2[j] == 0)
                 break;

                 longFileName[k] = LongNameDirectoryEntry_Local->dir_lname2[j];
                 k++;           
            }
           if(j >= 12)   
                for(j = 0;j < 4;j += 2)//读取longNameDirectoryEntry中的第三大作2个字节
                 { 
                  if (LongNameDirectoryEntry_Local->dir_lname3[j] == 0)
                     break;       
                    longFileName[k] = LongNameDirectoryEntry_Local->dir_lname3[j];
                    k ++;                   
                 }
          }
	 if(k > 242)
	  longFileName[k] = 0;
	CORE.PreEntrySectorNum = CORE.SectorNum;
    CORE.PreEntryoffset = CORE.offset;
	if(CORE_offset_add_32(buf) == FAIL) 
       return(FAIL);//Directory Entry的位置+32 
    FileNameOffset -= 13;
    k = FileNameOffset;
    LongNameDirectoryEntry_Local = (struct LongNameDirectoryEntry *) (buf + CORE.offset);
    if(LongNameDirectoryEntry_Local->dir_attr != ATTR_LONG_NAME)
	{      //遇到非ATTR_LONG_NAME表示一个LONG FILE NAME读怒即将结束,处理最后的short entry
           if ( ! (LongNameDirectoryEntry_Local->dir_attr & ATTR_VOLUME_ID)) 
           {//保存首簇号
			CORE.ClusterOfDirectoryEntry = LongNameDirectoryEntry_Local->dir_first[0]+
				LongNameDirectoryEntry_Local->dir_first[1] * 256;
			//保存文件长度
            CORE.FileSize = *((u32*)LongNameDirectoryEntry_Local->dir_lname3);
			//拷贝longFileName到变量longFileName
			stringcpy(longFileName+FileNameOffset+13,longFileName);
			//分离文件扩展名
			len =  LengthofString(longFileName);
			len --;
			i = 0;
			do{
				if(longFileName[len] == '.')
				{
				  longFileName[len] = 0;
                  stringcpy(longFileName + len + 1,Extension);
				  break;
				}
			   len--;
			   i++;
			   if(i >= 15 || len == 0 )
				 break;
			}while(1);
            break;
           }
       flag = FILE_NAME;
       FileNameOffset = 256 - 13;
       k = FileNameOffset; 
	   do{
		  CORE.PreEntrySectorNum = CORE.SectorNum;
          CORE.PreEntryoffset = CORE.offset;
          if(CORE_offset_add_32(buf) == FAIL) 
            return(FAIL); //Directory Entry的位置+32 
          LongNameDirectoryEntry_Local = (struct LongNameDirectoryEntry *) (buf + CORE.offset);
	      if(LongNameDirectoryEntry_Local->dir_lname1[0] == 0xe5)
             continue;//过滤已删除ENTRY
	      if(LongNameDirectoryEntry_Local->dir_attr != ATTR_LONG_NAME)
		  {
	       if ( ! (LongNameDirectoryEntry_Local->dir_attr & ATTR_VOLUME_ID)) 
            return(GetEntryWith8_3Name(buf,longFileName,Extension));
		   else
			 continue;
		  }
	      else
		   break;
	   } while(1);
     } 
  }while(1); 

  return(SUCC);
 }

              
/*===============================================================================
函数
从目录读取一个Entry
入口:mode = 0:返回所有directory entry
出口:SUCC,FAIL
===============================================================================*/     
static u8 GetEntryFromDirectory(u8 *EntryName, u8 *Extension,u8 mode)
{ 
struct Directory_Entry_  *Directory_Entry_Local; 
struct LongNameDirectoryEntry *LongNameDirectoryEntry_Local; 
u8 flag; 
u8 buf[512];
read_flash_sector(buf,CORE.SectorNum);
do{ 
  if(CORE.offset == 512)
  {
    return(FAIL);
  }
  flag = FILE_NAME; 
  Directory_Entry_Local = (struct Directory_Entry_ *) (buf + CORE.offset);
  if(Directory_Entry_Local->filename[0] == 0x0)//遇目录结尾,读取已至结尾,退出返回FAIL
	  return(FAIL);
  if(Directory_Entry_Local->filename[0] == 0xe5)//过滤已删除ENTRY
  {
   CORE.PreEntrySectorNum = CORE.SectorNum;
   CORE.PreEntryoffset = CORE.offset;
   if(CORE_offset_add_32(buf) == FAIL) //Directory Entry的位置+32 
     return(FAIL);
   continue;
  }  
  switch(Directory_Entry_Local->file_attribute) //检查file_attribute, 
    {
       case ATTR_LONG_NAME:{ //从目录读取长文件名
          if(GetEntryWithLongFileName(buf,EntryName,Extension) == SUCC)
          {	
		   read_flash_sector(buf,CORE.SectorNum);
           LongNameDirectoryEntry_Local = (struct LongNameDirectoryEntry *)(buf + CORE.offset);
		   CORE.Entry_Attr = LongNameDirectoryEntry_Local->dir_attr;
		   if(mode == Get_Selected_ENTRIES)

⌨️ 快捷键说明

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