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

📄 fat.c

📁 FAT16源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	   ///////////printf("Allocated Cluster %ld i = %d",NEXTCluster,i);
       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);
  FCB[FCBsn].Modified_Flag = 0;
  //Read File Directory entry
  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;
  //check FileSize is modified?
  if(FILESIZE != FCB[FCBsn].FileSize) 
  { //if filesize was increased,need to update filesize of the 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 

/*
===============================================================================
函数
根据文件的当前位置,更新FCB文件缓冲区
入口: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)
    if(Writeback_FCB_file_buffer(FCBsn) == FAIL)
	  return(FAIL);
	////////printf("Tony");
  //Initialize FCB file buffer
  FCB[FCBsn].CurBlockInBUF = FCB[FCBsn].cur_position / FileBUFSize;
  ClusterQTY = FCB[FCBsn].CurBlockInBUF / BPB.sector_per_cluster;
  NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  qty = ClusterQTY;
  
  
  if(FCB[FCBsn].ClusterSNInBUF_for_read <= ClusterQTY)
  { 
    ClusterQTY -= FCB[FCBsn].ClusterSNInBUF_for_read;
    NEXTCluster = FCB[FCBsn].CurClusterInBUF_for_read;
  }
 else
 {
    NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  } 




  while(ClusterQTY)
  {
   if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
	   return(SUCC);
   NEXTCluster =  Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
   ClusterQTY--;
  } 
  FCB[FCBsn].CurClusterInBUF_for_read = NEXTCluster;
  FCB[FCBsn].ClusterSNInBUF_for_read = qty; 


  FCBbufSize = FileBUFSize * TotalFileBUFsQTYeachFCB; 
  BUFoffset = 0;
  i = FCB[FCBsn].CurBlockInBUF % BPB.sector_per_cluster;
  sector = FirstSectorofCluster(NEXTCluster);
  do{  
   read_flash_sector(FCB[FCBsn].FileBUF + BUFoffset,sector + i); 
   BUFoffset += FileBUFSize;
   FCBbufSize -= FileBUFSize;
   if(FCBbufSize == 0)
    {
     return(SUCC); 
    }
   i++;
   if(i >= BPB.sector_per_cluster)
     {
       NEXTCluster= Get_Next_Cluster_From_Current_Cluster(NEXTCluster);
       if(NEXTCluster >= 0xfff4 && NEXTCluster <= 0xffff)
	   return(SUCC);
	   sector = FirstSectorofCluster(NEXTCluster);
       i = 0;
      }    
  }while(1);
}
#endif 

/*
===============================================================================
函数
分配一个FCB
入口:无
出口:EAllocate_FCB-- Fail,other--SUCC with FCB sequential number
===============================================================================
*/ 
u8 Allocate_FCB(void)
{  
 u8 i;
 for (i = 0; i < MaximumFCB;i++)
  if (FCB[i].file_openned_flag == UnusedFlag)
   {          
    FCB[i].file_openned_flag = UsedFlag;
	FCB[i].Modified_Flag = 0;
    return(i);
   }
 return(EAllocate_FCB);
}
/*
===============================================================================
函数
free a FCB
入口:FCB_sequential_number
出口:EFree_FCB,SUCC
===============================================================================
*/     
u8 Free_FCB(u8 FCB_sequential_number)
{
 if(FCB[FCB_sequential_number].file_openned_flag == UsedFlag)
  {
    FCB[FCB_sequential_number].file_openned_flag = UnusedFlag;
	FCB[FCB_sequential_number].Modified_Flag = 0;
    return(SUCC);
  }
  else
   return(EFree_FCB);
}
/*
===============================================================================
函数
FAT file system initialiation
入口:无
出口:无
===============================================================================
*/ 
#if complie_FAT_filesystem_initialiation
u8 FAT_filesystem_initialiation()
{ 
  u8 root[] = "C:\\",i;
  Directory_Entry.filename[0]  = 0;
  CORE.PartitionID = 0xff;
  CORE.CurrentDirectoryType =  RootDirectory; 
  stringcpy(root,CORE.current_folder);
  for (i = 0; i < MaximumFCB;i++)
  {
   FCB[i].file_openned_flag = UnusedFlag; //UsedFlag
   FCB[i].Modified_Flag = 0;
  }
  //read defalut partition BPB and related information to RAM buffer
  return(Read_partition_PBP(0)); 
} 
#endif


/*
===============================================================================
函数
auto format FAT16 file system
入口:无
出口:无
===============================================================================
*/ 
#if complie_FAT16_filesystem_autoformat
u8 FAT16_filesystem_autoformat(void)
{
 u8 buf[512];
 u16 i;
 if( read_flash_sector(buf,0) == SUCC ) //read MBR
 {   
      if ( ! ( buf[510] == 0x55 && buf[511] == 0xaa))
	  {   return(FAIL);
		  

        }
    }
 return(SUCC); 
} 
#endif
   

/*
===============================================================================
函数 
打开文件
入口:u8 * filename:路径+文件名
出口:返回PCB_SN,FAIL
===============================================================================
*/   
#if complie_open_file 
u8 open_file(u8 * filename)
{ 
 u8 FCBsn;
 CORE.FullPathType = FilePath; 
 if(FullPathToSectorCluster(filename) == SUCC)
 {  
     FCBsn = Allocate_FCB();
     if(FCBsn == EAllocate_FCB)
       return(FAIL);
     FCB[FCBsn].cur_position = 0;
	 FCB[FCBsn].CurBlockInBUF = 0xffff;
     //////////////////////////////printf("CORE.ClusterOfDirectoryEntry = %ld",CORE.ClusterOfDirectoryEntry);
     FCB[FCBsn].FirstClusterOfFile = CORE.ClusterOfDirectoryEntry;
     FCB[FCBsn].CurClusterInBUF = FCB[FCBsn].FirstClusterOfFile;
     FCB[FCBsn].ClusterSNInBUF = 0;

	 FCB[FCBsn].CurClusterInBUF_for_read= FCB[FCBsn].FirstClusterOfFile;
     FCB[FCBsn].ClusterSNInBUF_for_read = 0;


     FCB[FCBsn].FileSize = CORE.FileSize;
     FCB[FCBsn].Entry_Storedin_Sector = CORE.PreEntrySectorNum ;  //Save sectorNUM of File Directory entry for current file
     FCB[FCBsn].Entry_Storedin_Sector_Offset = CORE.PreEntryoffset; //Save offset in sector of File Directory entry for current file
     FCB[FCBsn].Modified_Flag = 0;
	 //第一个参数是文件的首簇号,第2个参数是文件对应的FCBsn,未分配FCB的文件使用0xff替代
	 if(Check_FileOpened_Status(CORE.ClusterOfDirectoryEntry,FCBsn) == FileAlreadyopenedByOtherHandle)
         FCB[FCBsn].Permission = ReadOnlyPermission;
	 else
         FCB[FCBsn].Permission = FullPermission;
   #if EnableFileBuf
     Update_FCB_file_buffer(FCBsn);
   #endif 
     return(FCBsn); 
   }
  else
   return(FAIL);
}
#endif 
/*
===============================================================================
函数 
关闭文件
入口:无
出口:SUCC,FAIL
===============================================================================
*/  
#if complie_close_file
u8 close_file(u8 FCBsn)
{  
  if(Free_FCB(FCBsn) == SUCC)
    return(SUCC);
  else
    return(FAIL);
} 
#endif  
/*
===============================================================================
函数
Directory Entry offset+32 由建立文件和目录使用,遇末簇可自动分配空簇加入簇链
入口:buf--Current Sector Buffer
出口:SUCC,FAIL
===============================================================================
*/             
static u8 CORE_offset_add_32_With_EMPTY_CLUSTER_ALLOCATION(u8 *buf)
{
  u32 temp;
  CORE.offset += 32;
  if (CORE.offset >= 512)
  {
   CORE.SectorNum++;
  if (CORE.DirectoryType == RootDirectory)
  {     
        if (CORE.SectorNum < ( CORE.RootDirSectors +  CORE.FirstRootDirSecNum))
         {
           
           CORE.offset = 0; 
           read_flash_sector(buf,CORE.SectorNum);
           return(SUCC);
         }
        else
           return(FAIL);
     }
    else  
     {
        if( (CORE.SectorNum - FirstSectorofCluster(CORE.ClusterNum) + 1) > BPB.sector_per_cluster)
         {
		   temp  = CORE.ClusterNum;
           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);
               return(SUCC);
            }
           else
		   {   //遇末簇,自动分配空簇加入簇链 
			   if(Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(temp,&temp,buf) == FAIL)
				   return(FAIL);
               CORE.ClusterNum = temp;
               CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum); 
               CORE.offset = 0;

               read_flash_sector(buf,CORE.SectorNum);
			   return(SUCC);
		   }
         }
        else
         {
            CORE.offset = 0;
            read_flash_sector(buf,CORE.SectorNum);
            return(SUCC);
         }
     }
  }
  return(SUCC);
}
/*
===============================================================================
函数 
计算longfilenameentry校验和
入口:*entry:longfilenameentry首地址
出口:checksum
===============================================================================
*/
static u8 calculate_checksum_longfilenameentry(u8 *entry)
{
 u8 sum,i;
 sum=0;
 i = 0;
 while (i < 11)
  {
   sum = (sum >> 1) | (sum << 7);
   sum += entry[i];
   i++;
  }
  return(sum);
}
/*
===============================================================================
函数 
添加一个Directory_Entry到目录,目录首簇值为CORE.ClusterOfDirectoryEntry或
CORE.FirstRootDirSecNum
入口:Directory_Entry:Directory_Entry name,attr:attr of Directory_Entry
出口:SUCC,FAIL
===============================================================================
*/
static u8 Seek_Space_to_Write_Directory_Entry(u16 Entry_Resuested_QTY,u8 *buf)
{
  u32 SectorNum_LOCAL,ClusterNum_LOCAL;
  u16 Offset_LOCAL;
  u8 Empty_Entry_Space_Count,found_flag;
  if(CORE.DirectoryType == RootDirectory)
  {
    CORE.SectorNum = CORE.FirstRootDirSecNum;
  }
  else
  { //////printf("CORE.ClusterOfDirectoryEntry %ld",CORE.ClusterOfDirectoryEntry);
    CORE.ClusterNum = CORE.ClusterOfDirectoryEntry;   //存放当前Enumerated Directory Entry所在Directory的ClusterNum,SectorNum,offset
    CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
  } 
  CORE.offset = 0;
////////printf("aaaaaaaaaaaaaaaaCORE.SectorNum %ld CORE.ClusterNum %ld CORE.offset %ld",
//  CORE.SectorNum,CORE.ClusterNum
//   ,CORE.offset);
  read_flash_sector(buf,CORE.SectorNum);
  while(1)
  { 
    SectorNum_LOCAL = CORE.SectorNum; 
    ClusterNum_LOCAL = CORE.ClusterNum;
    Offset_LOCAL = CORE.offset;
	found_flag = 0;
	Empty_Entry_Space_Count = 0;
    do{
       if(buf[CORE.offset] == 0xe5 || buf[CORE.offset] == 0)
	   {
	    Empty_Entry_Space_Count++;
	    if(Empty_Entry_Space_Count >= Entry_Resuested_QTY)
		{
	     found_flag = 1;
	     break;
		}
	   }
	   else
	     break;

⌨️ 快捷键说明

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