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

📄 fat.c

📁 嵌入式FAT文件系统源码免费下载
💻 C
📖 第 1 页 / 共 5 页
字号:
		   {
             if(CORE.CurPathType == DirectoryPath && 
               (LongNameDirectoryEntry_Local->dir_attr & ATTR_DIRECTORY))
			 { 
               CORE.ClusterOfDirectoryEntry = *(u16*)LongNameDirectoryEntry_Local->dir_first;
               CORE.PreEntrySectorNum = CORE.SectorNum;
               CORE.PreEntryoffset = CORE.offset;
			   CORE_offset_add_32(buf);///Directory Entry的位置+32 
               return(SUCC);
			 }
             else if ( ! (LongNameDirectoryEntry_Local->dir_attr & ATTR_VOLUME_ID)) 
			 {
              CORE.PreEntrySectorNum = CORE.SectorNum;
             CORE.PreEntryoffset = CORE.offset;
			 CORE_offset_add_32(buf);//Directory Entry的位置+32 
             return(SUCC);
             }	   
		   }
		   else
		   {
			CORE.PreEntrySectorNum = CORE.SectorNum;
            CORE.PreEntryoffset = CORE.offset;
		    CORE.ClusterOfDirectoryEntry = *(u16*)LongNameDirectoryEntry_Local->dir_first;
            CORE_offset_add_32(buf);//Directory Entry的位置+32 
            
			return(SUCC);
		   }
          }
          break;
        }
       case ATTR_DIRECTORY:{//从目录读取目录(短文件名)
		  CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
		  if(mode == Get_Selected_ENTRIES)
           if(CORE.FullPathType == FilePath && CORE.CurPathType == FilePath)
             break;
          if(GetEntryWith8_3Name(buf,EntryName,Extension)  == SUCC)
             return(SUCC);       
          break;
       }
       case ATTR_VOLUME_ID:CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
       //case 0:break;
       default:
        {//从目录读取文件(短文件名)
		 CORE.Entry_Attr = Directory_Entry_Local->file_attribute;
	     if(mode == Get_Selected_ENTRIES)
          if(CORE.FullPathType == DirectoryPath)
             break;
          return(GetEntryWith8_3Name(buf,EntryName,Extension)); 
        }
     } 
  CORE.PreEntrySectorNum = CORE.SectorNum;
  CORE.PreEntryoffset = CORE.offset;
  if(CORE_offset_add_32(buf) == FAIL) 
    return(FAIL);//Directory Entry的位置+32 
 }while(1); 
return(SUCC);
}  
/*===============================================================================
函数
从目录中查找一个Entry
入口:floder_name-文件名,file_extension-扩展名
出口:SUCC,FAIL
===============================================================================*/
static u8 FindEntryStruct(u8 *floder_name,u8 *file_extension)
{  
   u8 EntryName[256],Extension[20]; 
   u8 Name_Compare_OK,Extension_Compare_OK;   
   do{	  //从目录读取一个Entry	   
          if(GetEntryFromDirectory(EntryName,Extension,Get_Selected_ENTRIES) != SUCC)
		  {
            return(FAIL);
		  }
       Name_Compare_OK = OK;
	   //检查文件名
       if(stringcmp(EntryName,floder_name) != SUCC)
             Name_Compare_OK = unOK;        
       if(Name_Compare_OK == OK)  //检查文件扩展名
         {      
           if(CORE.FullPathType == FilePath && CORE.CurPathType == FilePath)
              { 
					
                  Extension_Compare_OK = OK;     
                  if(stringcmp(Extension,file_extension) != SUCC)
                     Extension_Compare_OK = unOK;
                  else
                     break;  
              }
            else
			{  	
                if(Extension[0] == 0) 
                 break;

              }  
          }
     }while(1);
   return(SUCC);
}
/*===============================================================================
函数
相对的路径转换成Sector,SectorOffset,Cluster
入口:u8 *filename
出口:SUCC,FAIL
===============================================================================*/
static u8 RelativePathToSectorCluster(u8 *RelativePath)
{ 
  u8 floder_name[256],file_extension[20]; 
  u8 Splited_Count;
  u8 Splited_Status;
   //调用SplitNameFromPath()从RelativePath分离出一个目录或文件元素
  Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
  if(Splited_Status == FAIL)
      return(FAIL);
  RelativePath += Splited_Count;  
   //从目录中查找一个Entry
  if(FindEntryStruct(floder_name,file_extension) != SUCC)
  {
   return(FAIL); //查找失败退出
  }//DirectoryType置为非RootDirectory
   if(CORE.CurPathType == DirectoryPath)
     if(CORE.DirectoryType == RootDirectory)
	  {
	  CORE.DirectoryType = NoneRootDirectory; 
	  }
      
  if(Splited_Status == LastSplitedNameofPath)
  {
   return(SUCC); 
  }    
  do{ //调用SplitNameFromPath()从RelativePath分离出一个目录或文件元素
     Splited_Status = SplitNameFromPath(RelativePath,floder_name,file_extension,&Splited_Count);
     if(Splited_Status == FAIL)
	  return(FAIL);    
     else 
       { //设置变量,进入目录去查找
         CORE.ClusterNum = CORE.ClusterOfDirectoryEntry;
         CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
         CORE.offset = 0;  
       }
     RelativePath += Splited_Count;
	 //DirectoryType置为非RootDirectory
     if(CORE.CurPathType == DirectoryPath)
      if(CORE.DirectoryType == RootDirectory)
	  {
	  CORE.DirectoryType = NoneRootDirectory; 
	  }
	  //从目录中查找一个Entry
     if(FindEntryStruct(floder_name,file_extension) != SUCC)
	 {
       return(FAIL); //查找失败退出
	 }
     else if(Splited_Status == LastSplitedNameofPath)
	 {
      return(SUCC);
	 }  

    }while(1);
    return(SUCC);
}
/*===============================================================================
函数
完整的路径转换成Sector,SectorOffset,Cluster,可用于检查文件是否存在
入口:u8 *filename
出口:SUCC,FAIL
===============================================================================*/
static u8 FullPathToSectorCluster(u8 * filename1)
{
   u8 buf[260],* filename;
   stringcpy(filename1,buf);
   filename = buf;
   UPCASE(filename);

     if( ((* filename) >= 'A' && ( * filename ) <= 'Z')||
		((* filename) >= 'a' && ( * filename ) <= 'z') )  
       {
         if(( * (filename + 1)) == ':')
          {                          
           if( *( filename + 2 ) == '\\')
            { //绝对路径,从根目录进行转换
              if(LengthofString(filename) > Maximum_File_Path_Name)
			      return(EpathLengthsOVERFLOW);
              if(Read_partition_PBP((u8)((*filename) - 'C')) != SUCC)
                 return(FAIL);
              filename += 3; 
			  //设置参数,根目录寻址
              CORE.SectorNum = CORE.FirstRootDirSecNum; 
              CORE.DirectoryType =  RootDirectory;
              CORE.offset = 0;   
             }
          }
         else 
		 {   //相对路径,从当前目录进行转换  
             if((LengthofString(filename) + LengthofString(CORE.current_folder)) > Maximum_File_Path_Name)
                   return(EpathLengthsOVERFLOW);
             //设置参数
			 if(CORE.CurrentDirectoryType ==  RootDirectory)
			 {
			    CORE.SectorNum = CORE.FirstRootDirSecNum;
			 }  
             else
              {
                 CORE.ClusterNum = CORE.ClusterNOofCurrentFolder;
                 CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum); 
              }
             CORE.DirectoryType = CORE.CurrentDirectoryType;
             CORE.offset = 0;	 

          }  
       }
       else if((* filename) == '\\')//从当前盘符进行转换
            {
             if((LengthofString(filename) + 1) > Maximum_File_Path_Name)
                   return(EpathLengthsOVERFLOW); 
              //设置参数,根目录寻址
             filename ++;    
             CORE.SectorNum = CORE.FirstRootDirSecNum; 
             CORE.DirectoryType = RootDirectory;
             CORE.offset = 0;

            } 
  if(*filename)
     return(RelativePathToSectorCluster(filename));
  else
	return(SUCC);
   
}
/*===============================================================================
函数
检查文件是否已打开?
入口:FirstClusterOfFile-文件首簇号
出口:FileAlreadyopenedByOtherHandle,FileUnopenedByOtherHandle
===============================================================================*/ 
u8 Check_FileOpened_Status(u32 FirstClusterOfFile,u16 j)
{
  u8 i;
  for(i = 0;i < MaximumFCB;i++)
  {
    if(i == j)
		continue;
   if(FCB[i].file_openned_flag == UsedFlag)
   { //FCB的首簇号与文件首簇号相同,则文件已被打开
     if(FCB[i].FirstClusterOfFile == FirstClusterOfFile)
        return(FileAlreadyopenedByOtherHandle);
   }
  }
  //未发现相同首簇号,文件未打开,返回
  return(FileUnopenedByOtherHandle);
} 
/*===============================================================================
函数
将file buffer回写磁盘
入口:u8 FCBsn
出口:SUCC,FAIL
===============================================================================*/ 
#if EnableFileBuf
u8 Writeback_FCB_file_buffer(u8 FCBsn)
{ 
  u16 i;
  u16 ClusterQTY,BUFoffset,TEMP;
  u32 FCBbufSize,sector,NEXTCluster,qty; 
  u8  buf[512];
  u32 FILESIZE;
  u16 wrote_sectors_count;
  
  if(FCB[FCBsn].FirstClusterOfFile == 0)
  { //未分配文件首簇号,则执行分配
	if( Allocate_An_Empty_cluster(&FCB[FCBsn].FirstClusterOfFile,buf)== FAIL)
	  return(FAIL);
	//将首簇号写入文件的ENTRY内
	read_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
    i = FCB[FCBsn].Entry_Storedin_Sector_Offset + 26;
	buf[i] = (u8)(FCB[FCBsn].FirstClusterOfFile & 0xff);
	buf[i+1] = (u8)((FCB[FCBsn].FirstClusterOfFile >> 8) & 0xff);
	write_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
    FCB[FCBsn].CurClusterInBUF = FCB[FCBsn].FirstClusterOfFile;
  }
  //根据当前CurBlockInBUF计算需要移动CLUSTER数量
  ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
  NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  //计算需要移动CLUSTER数量
  qty = ClusterQTY;
  if(FCB[FCBsn].ClusterSNInBUF <= ClusterQTY)
  {
    ClusterQTY -= FCB[FCBsn].ClusterSNInBUF;
    NEXTCluster = FCB[FCBsn].CurClusterInBUF;
  }
  else
  {
    NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  }
  //移动CLUSTER
  while(ClusterQTY)
  {TEMP = NEXTCluster;
   NEXTCluster =  Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
   ClusterQTY--;
   if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
	   {
	    if (Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(TEMP,&NEXTCluster,buf) == FAIL)
			return(FAIL);
	   }
  } 

  //保存当前CurClusterInBUF及ClusterSNInBUF
  FCB[FCBsn].CurClusterInBUF = NEXTCluster;
  FCB[FCBsn].ClusterSNInBUF = qty; 
  //将file buffer回写磁盘
  FCBbufSize = FileBUFSize * TotalFileBUFsQTYeachFCB; 
  BUFoffset = 0;
  i = FCB[FCBsn].CurBlockInBUF % BPB.sector_per_cluster;
  //获取首扇区
  sector = FirstSectorofCluster(NEXTCluster);
  wrote_sectors_count = 0; 
  do{ 
     write_flash_sector(FCB[FCBsn].FileBUF + BUFoffset,sector + i); 
     wrote_sectors_count++;
	 i++;
	 //超过FILE SIZE直接退出
	 if(((wrote_sectors_count + FCB[FCBsn].CurBlockInBUF) * 512) >= FCB[FCBsn].FileSize)
	 {
	    break;
	 }
     BUFoffset += FileBUFSize;
     FCBbufSize -= FileBUFSize;
     if(FCBbufSize == 0)
	 {
	 break;
	 }
     if(i >= BPB.sector_per_cluster)
	 { //超过簇边界, 转到下一簇继续写 
	   TEMP = NEXTCluster; 
       NEXTCluster = Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
       if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
	   {
	    if (Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(TEMP,&NEXTCluster,buf) == FAIL)
			return(FAIL);
	   }
	   sector = FirstSectorofCluster(NEXTCluster);
       i = 0;
      }    
  }while(1);
  //清除Modified_Flag
  FCB[FCBsn].Modified_Flag = 0;
  //读取文件目录项, 从而更新文件大小
  read_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
  i = FCB[FCBsn].Entry_Storedin_Sector_Offset + 28;
  FILESIZE = buf[i] + buf[i+1] * 256 + buf[i+2] * 256 * 256+ buf[i+3]  * 256 * 256 *256;
  //检查文件大小是否已更新?
  if(FILESIZE != FCB[FCBsn].FileSize) 
  { //检查文件大小已更新,则更新File Directory entry的文件大小
	FILESIZE = FCB[FCBsn].FileSize;
	buf[i] = (u8)(FILESIZE & 0xff);
	buf[i+1] = (u8)((FILESIZE >> 8) & 0xff);
	buf[i+2] = (u8)((FILESIZE >> 16) & 0xff);
	buf[i+3] = (u8)((FILESIZE >> 24) & 0xff);
    write_flash_sector(buf,FCB[FCBsn].Entry_Storedin_Sector);
  }
  return(SUCC);
}
#endif 

/*===============================================================================
函数
基于文件当前的位置,完成更新文件缓冲区
入口:u8 FCBsn
出口:SUCC,FAIL
===============================================================================*/ 
#if EnableFileBuf
u8 Update_FCB_file_buffer(u8 FCBsn)
{ 
  u16 i;
  u16 ClusterQTY,BUFoffset;
  u32 FCBbufSize,sector,NEXTCluster,qty; 
  if(!(FileBUFSize * TotalFileBUFsQTYeachFCB))
     return(SUCC);
  if(((FCB[FCBsn].cur_position) >= FCB[FCBsn].CurBlockInBUF * FileBUFSize && 
     ((FCB[FCBsn].cur_position) <  (FCB[FCBsn].CurBlockInBUF + TotalFileBUFsQTYeachFCB) * FileBUFSize) ))
  {
  return(SUCC); 
  }
  if(FCB[FCBsn].Modified_Flag)//检查Modified_Flag,如果不为0,则需要回写FILE BUFFER
    if(Writeback_FCB_file_buffer(FCBsn) == FAIL)
	  return(FAIL);
  //根据当前CurBlockInBUF计算需要移动CLUSTER数量
  FCB[FCBsn].CurBlockInBUF = FCB[FCBsn].cur_position / FileBUFSize;
  ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
  NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  qty = ClusterQTY;
  
  //计算需要移动CLUSTER数量  
  if(FCB[FCBsn].ClusterSNInBUF_for_read <= ClusterQTY)
  { 
    ClusterQTY -= FCB[FCBsn].ClusterSNInBUF_for_read;
    NEXTCluster = FCB[FCBsn].CurClusterInBUF_for_read;

⌨️ 快捷键说明

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