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

📄 fat.c

📁 嵌入式FAT文件系统源码免费下载
💻 C
📖 第 1 页 / 共 5 页
字号:
  }
 else
 {
    NEXTCluster = FCB[FCBsn].FirstClusterOfFile; 
  } 

  //移动CLUSTER
  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++)//找一个UnusedFlag的FCB,返回给调用者使用
  if (FCB[i].file_openned_flag == UnusedFlag)  
   {          
    FCB[i].file_openned_flag = UsedFlag;//设置为占用
	FCB[i].Modified_Flag = 0;
    return(i);//返回FCB的编号
   }
 return(EAllocate_FCB);
}
/*===============================================================================
函数
释放一个FCB
入口:FCB_sn
出口:EFree_FCB,SUCC
===============================================================================*/     
u8 Free_FCB(u8 FCBsn)
{//检查FCB是否占用
 if(FCB[FCBsn].file_openned_flag == UsedFlag)
  {
    FCB[FCBsn].file_openned_flag = UnusedFlag;//设置为非占用
	FCB[FCBsn].Modified_Flag = 0;
    return(SUCC);
  }
  else
   return(EFree_FCB);
}
/*===============================================================================
函数
FAT初始化函数,一般由main()在使用文件系统之前调用
入口:无
出口:无
===============================================================================*/ 
#if complie_FAT_filesystem_initialiation
u8 FAT_filesystem_initialiation(void)
{ 
  u8 root[] = "C:\\",i;
  CORE.PartitionID = 0xff;
  CORE.CurrentDirectoryType =  RootDirectory; 
  //初始化当前目录为'C:\'
  stringcpy(root,CORE.current_folder);
  //所有FCB设置为非占用
  for (i = 0; i < MaximumFCB;i++)
  {
   FCB[i].file_openned_flag = UnusedFlag; 
   FCB[i].Modified_Flag = 0;
  }
  //读取缺省的PBP和相关的信息
  return(Read_partition_PBP(0)); 
} 
#endif


struct mbr MBR;

//write fat1/2
//    Parameter: none      
//    Return:none
//
static void write_fat(u8 disk_)
{
 U8 buf[512];
 U32 i;//,begin_sector,counter_of_sector;
 for(i = 0;i<512;i++)
	 buf[i] = 0x0;

 for(i = 1;i<10000;i++)
  write_flash_sector(buf,i);
 //run block erase, clr root/fat1/2 region
 //while(block_erase(1,1+SDs_BlockNum-2)== FAIL);

 buf[0] = 0xf8;buf[1] = 0xff;buf[2] = 0xff;buf[3] = 0xff;
 write_flash_sector(buf,1); 
 write_flash_sector(buf,257); 

}
// fill mbr and write fat1/2, root
//    Parameter: Tsectors-- total sector on the partition     
//    Return:none
//
static void fill_mbr_and_write_fat_root(U32 Tsectors,U8 disk_)
{U32 i;
 MBR.BS_jmpBoot[0] = 0XEB;
 MBR.BS_jmpBoot[1] = 0X3C;
 MBR.BS_jmpBoot[2] = 0X90;
 MBR.flag[0] = 0x55;
 MBR.flag[1] = 0xaa;
 MBR.BS_OEMName[0] = 'c';
 MBR.BS_OEMName[1] = 'e';
 MBR.BS_OEMName[2] = 'o';
 MBR.BS_OEMName[3] = ' ';
 MBR.BS_OEMName[4] = 's';
 MBR.BS_OEMName[5] = 'o';
 MBR.BS_OEMName[6] = 'f';
 MBR.BS_OEMName[7] = 't';
 /*write bpb*/

 /*BPB_BytsPerSec = 512*/
 MBR.BPB_BytsPerSec[0] = 0;
 MBR.BPB_BytsPerSec[1] = 2;
 /* BPB_SecPerClus*/
 MBR.BPB_SecPerClus = 64;
 /* RESERVED SECTOR COUNTER = 1*/
 MBR.BPB_RsvdSecCnt[0] = 1;
 MBR.BPB_RsvdSecCnt[1] = 0;
 /*NUM of FATS*/
 MBR.BPB_NumFATs = 2;
 /* RootEntCnt = 1024*/
 MBR.BPB_RootEntCnt[0] = 0x00;
 MBR.BPB_RootEntCnt[1] = 0x4; 
 /* TotSec16[2] = 0*/
 MBR.BPB_TotSec16[0] = 0x0;
 MBR.BPB_TotSec16[1] = 0x0;
 /*0xF8 is the standard value for “fixed”*/
 MBR.BPB_Media = 0XF8;
 /* This field is the FAT12/FAT16 16-bit count of sectors occupied by
ONE FAT*/
 MBR.BPB_FATSz16[0] = 0;
 MBR.BPB_FATSz16[1] = 1;

/*BPB_TotSec32*/
 MBR.BPB_TotSec32[0] = (U8)(Tsectors & 0xff); 
 MBR.BPB_TotSec32[1] = (U8)((Tsectors >> 8) & 0xff);
 MBR.BPB_TotSec32[2] = (U8)((Tsectors >> 16) & 0xff);
 MBR.BPB_TotSec32[3] = (U8)((Tsectors >> 24) & 0xff);
 for(i = 0;i<448;i++)
	 MBR.pad[i] = ' ';
 MBR.BS_FilSysType[0] = 'F';
 MBR.BS_FilSysType[1] = 'A';
 MBR.BS_FilSysType[2] = 'T';
 MBR.BS_FilSysType[3] = '1';
 MBR.BS_FilSysType[4] = '6';
 MBR.BS_FilSysType[5] = ' ';
 MBR.BS_FilSysType[6] = ' ';
 MBR.BS_FilSysType[7] = ' ';
 for(i = 0;i<11;i++)
  MBR.BS_VolLab[i] = ' ';
 MBR.BS_DrvNum = 0X0;
 MBR.BS_Reserved1 = 0;
 MBR.BS_BootSig = 0X29;
 MBR.BS_VolID[0] = 0XB9;
 MBR.BS_VolID[1] = 0XD2;
 MBR.BS_VolID[2] = 0X8F;
 MBR.BS_VolID[3] = 0XA8;
 write_flash_sector((U8 *)(&MBR),0);  
 //write_root();
 write_fat(disk_);
}
  
/*===============================================================================
函数
自动格式化 FAT 文件系统
入口:disk_:盘符   filesystem_type:以FAT16,FAT32为格式化目标  disk_capacity:磁盘容量
出口:SUCC,FAIL
===============================================================================*/ 
#if complie_FAT16_filesystem_autoformat
u8 FAT_filesystem_autoformat(u8 disk_,u8 filesystem_type,u32 disk_capacity)
{
 u8 buf[512];
 if( read_flash_sector(buf,0) == SUCC ) //read MBR
 {   
     if ( ! ( buf[510] == 0x55 && buf[511] == 0xaa))
	  {  
		  
		 if(filesystem_type== FAT16)
	    	  fill_mbr_and_write_fat_root(disk_capacity,disk_);
         else
		 {

		 }
	  
	  }
    }
 return(SUCC); 
} 
#endif
   

/*===============================================================================
函数 
打开文件
入口:u8 * filename:路径+文件名
出口:返回FCB_SN,FAIL
===============================================================================*/   
#if complie_open_file 
u8 open_file(u8 * filename)
{ 
 u8 FCBsn;
 CORE.FullPathType = FilePath; 
 //检查文件是否存在?
 if(FullPathToSectorCluster(filename) == SUCC)
 {   //有这个文件,则执行FCB分配
     FCBsn = Allocate_FCB();
     if(FCBsn == EAllocate_FCB)
       return(FAIL);
     //初始化FCB的各个参数
	 FCB[FCBsn].cur_position = 0;
	 FCB[FCBsn].CurBlockInBUF = 0xffff;
	 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;
	 //检查文件是否已打开?
	 if(Check_FileOpened_Status(CORE.ClusterOfDirectoryEntry,FCBsn) == FileAlreadyopenedByOtherHandle)
         FCB[FCBsn].Permission = ReadOnlyPermission;
	 else
         FCB[FCBsn].Permission = FullPermission;
   //调用Update_FCB_file_buffer(),将文件读取到文件缓冲区
   #if EnableFileBuf
     Update_FCB_file_buffer(FCBsn);
   #endif 
     return(FCBsn); 
   }
  else
   return(FAIL);//文件不存在,文件打开失败
}
#endif 
/*===============================================================================
函数 
关闭文件
入口:FCBsn
出口:SUCC,FAIL
===============================================================================*/  
#if complie_close_file
u8 close_file(u8 FCBsn)
{  
  if(Free_FCB(FCBsn) == SUCC)//释放FCB
    return(SUCC);
  else
    return(FAIL);
} 
#endif 
 
/*===============================================================================
函数
Directory Entry offset+32 由建立文件/目录使用,遇末簇可自动分配空簇加入簇链
入口:buf--
出口:SUCC,FAIL
===============================================================================*/             
static u8 CORE_offset_add_32_With_EMPTY_CLUSTER_ALLOCATION(u8 *buf)
{
  u32 temp;
  //位置+32
  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);
}
/*===============================================================================
函数 
计算长文件目录项的校验和
入口:*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的空间
入口:Entry_Resuested_QTY-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
  { 

⌨️ 快捷键说明

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