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

📄 fat.c

📁 嵌入式FAT文件系统源码免费下载
💻 C
📖 第 1 页 / 共 5 页
字号:
/*+FHDR------------------------------------------------------------------
版权所有:

杨文斌-专注USB与FAT文件系统的固件研究
联系方式:qq 292942278  电邮:tony_yang123@sina.com.cn

代码FAT16是免费代码,你可以测试,设计与研究它
我们有FAT32代码,收费的版本,你可与作者联系并购买

Copyright (c),
Tony Yang –Specialized in the USB and FAT's firmware research and design
Contact method:qq 292942278  e-mail:tony_yang123@sina.com.cn

This code of FAT16 is free code, you can test, design, research of it 
as your freedom, also the code with FAT32 code vision is for charge version
pls contact with author when you want it to buy of it.

Abstract:
$Id: main.C,v 1.1.1.1 2007/01/01 10:35:32 tony Exp $
-FHDR-------------------------------------------------------------------*/
 
#include<stdio.h>
#include<include\types.h>
#include<Flash_Management\Flash_Management.h>   
#include<include\FAT_cfg.h>
//data struct CORE definition
static struct core_ CORE;
//BPB data struct definition
static struct partition_bpb BPB; 
//FCG data struct definition 
struct FileControlBlock FCB[MaximumFCB];
/*===============================================================================
函数
转换字符串成大写
入口:*string:字符串的地址
出口:SUCC
===============================================================================*/ 
static u8 UPCASE(u8* string) 
{ 
 while(*string) 
 { 
     if(*string >='a' && *string <= 'z')
      {
  	   *string -= 32;
      }
	 string++;
   }    
 return(SUCC);
}
/*===============================================================================
函数
字符串的长度的获得
入口:*string:字符串的地址
出口:字符串的总长度
===============================================================================*/ 
static u16 LengthofString(u8 * string)
{ 
 u16 i;
 i = 0;
 while(*string)//字符数的计数,直到遇到=0
  {
    i++;
    string++;
  }
 return(i);
} 
/*===============================================================================
函数
连接两个字符串,字符串2连接后不变
入口:*string:字符串的地址
出口:SUCC,FAIL
===============================================================================*/ 
static u8 concanenateString(u8 *string1,u8 *string2)
{
  u8 len,i;
  len = LengthofString(string1);
  i = 0;
  while(string2[i])
  {  
    string1[len] = string2[i];  
    len++;
	i++;
  }
  string1[len] = 0;
  return(SUCC);
}

/*===============================================================================
函数
拷贝字符串,字符串1到字符串2的拷贝
入口:*string1:字符串的地址;*string2:字符串的地址
出口:SUCC
===============================================================================*/ 
static u8 stringcpy(u8 *string1,u8 *string2)
{
 while(*string1) 
   { //逐字字符串拷贝
     *string2 = *string1;
     string1++;
     string2++;
   }  
 *string2 = 0;
 return(SUCC);
}
/*===============================================================================
函数
比较两个字符串(字符串的大小写不用区分)
入口:*string1:字符串1的地址;*string2:字符串2的地址
出口:SUCC,FAIL
===============================================================================*/ 
static u8 stringcmp(u8 *string1,u8 *string2)
{
 UPCASE(string1);
 UPCASE(string2);  
 while((*string1) && (*string2)) 
   {
     if((*string1) == (*string2))
	 {   //逐字字符串比较
         string1++;
         string2++;
      }
     else
       return(FAIL);
   }   
 //判断两字符串尾都是0吗?  
 if( ((*string1) == 0) && ((*string2) == 0))
 {
     return(SUCC);
 }
 else
     return(FAIL);
}

/*===============================================================================
函数
在簇链里找到当前簇的下一簇
入口:Cluster:当前簇号
出口: 返回下一簇号
===============================================================================*/ 
static u32 Get_Next_Cluster_From_Current_Cluster(u32 Cluster)
{
   u8 buf[512]; 
   u32 ThisFATSecNum,ThisFATEntOffset;
   //FAT16每个簇占用两个字节
   ThisFATEntOffset = Cluster * 2;
   //计算当前簇所在扇区
   ThisFATSecNum = CORE.relative_sector + BPB.reserved_sector 
                   + (ThisFATEntOffset / BPB.bytes_per_sector);
   //计算当前簇所在扇区的偏移量
   ThisFATEntOffset = ThisFATEntOffset % BPB.bytes_per_sector; 
   //读取当前簇所在扇区
   read_flash_sector(buf,ThisFATSecNum);
   //返回当前簇的下一簇
   return((u32)buf[ThisFATEntOffset] + ((u32)buf[ThisFATEntOffset + 1]) * 256);
}
/*===============================================================================
函数
在簇链里找到当前簇上一的簇号
入口:Cluster:当前簇号
出口: 返回当前簇之前的簇号
===============================================================================*/ 
static u32 Get_Previous_Cluster_From_Current_Cluster(u32 Cluster)
{
  u8 buf[512];
  u32 CUR_FATSecNum,CUR_FATEntOffset;
  u32 CUR_Checking_Cluster_No;
  //从簇号0开始找
  CUR_Checking_Cluster_No = 0;
  CUR_FATEntOffset = 0;
  CUR_FATSecNum = CORE.FirstSectorofFAT1; 
  read_flash_sector(buf,CUR_FATSecNum); 
  do{ 
	 //超出最大簇号,查找失败
	 if( CUR_Checking_Cluster_No == (CORE.CountofClusters + 2))
         {
          return(FAIL);
         } 
	 //检查下一簇是否是当前簇号?
     if( (u16)(buf[CUR_FATEntOffset] + buf[CUR_FATEntOffset + 1] * 256) == (u16)Cluster)
          return(CUR_Checking_Cluster_No);  //返回簇号
     CUR_Checking_Cluster_No++;
     CUR_FATEntOffset += 2;

     if(CUR_FATEntOffset >= 512)//检查了一个扇区,继续到下一扇区检查
      {
        CUR_FATSecNum++;

        read_flash_sector(buf,CUR_FATSecNum); 
        CUR_FATEntOffset = 0;     
      }
  }while(1);
}
/*===============================================================================
函数
删除一个簇链
入口:Cluster:首簇号
出口: SUCC,FAIL
===============================================================================*/ 
static u8 FreeClusterChain(u32 Cluster)
{
 u8 buf[512],i; 
 u32 ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;    
 do{
   
   //FAT16每个簇占用两个字节
   ThisFATEntOffset = Cluster * 2;
   //计算当前簇所在扇区
   ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector 
                   + (ThisFATEntOffset / BPB.bytes_per_sector);
   ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;

   //计算当前簇所在扇区的偏移量
   ThisFATEntOffset = (ThisFATEntOffset) % BPB.bytes_per_sector; 
   read_flash_sector(buf,ThisFAT1SecNum);
   //Cluster置为其下一簇
   Cluster = (u32)buf[ThisFATEntOffset]+ (u32)buf[ThisFATEntOffset + 1] * 256;  
   //将簇值清0,
   buf[ThisFATEntOffset] = 0x0;  
   buf[ThisFATEntOffset + 1] = 0x0;
   //回写FAT1
   write_flash_sector(buf,ThisFAT1SecNum); 
   //回写FAT2及所有FAT表
   for(i = 1;i < BPB.numbers_of_FAT;i++) 
     {
      write_flash_sector(buf,ThisFAT2SecNum);
      ThisFAT2SecNum = ThisFAT2SecNum + BPB.sectors_per_FAT;
     } 
   //判断簇链是否结束?
   if(Cluster >= 0xfff6)
     return(SUCC);   
  }while(1);  
}
/*===============================================================================
函数
返回簇N的首扇区
入口:N:簇号
出口: 返回簇N的首扇区
===============================================================================*/  
static u32 FirstSectorofCluster(u32 N)
{
 return((N - 2) * BPB.sector_per_cluster + CORE.FirstDataSector);
}

/*===============================================================================
函数
从FAT中分配一个簇到簇链当前簇之后
入口:Cluster:当前簇号,added_cluster被分配的簇
出口: 加入的簇号
===============================================================================*/ 
u8 Allocate_EMPTY_CLUSTER_TO_CUR_CLUSTER_CHAIN(u32 Cluster,u32 *Added_Cluster,u8 *buf)
{
  u32 temp,EMPTY_CLUSTER,ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;
  u16 i; 
  EMPTY_CLUSTER = 0;
  //从起始FAT表的起始扇区,找空簇以完成分配
  ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector;
  ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
  do{    
  //从偏移量0开始找	  
  ThisFATEntOffset = 0; 
  read_flash_sector(buf,ThisFAT1SecNum);   
  for(i = 0;i < 256;i++)
  {  
     if(buf[ThisFATEntOffset] == 0 && buf[ThisFATEntOffset + 1] == 0)
      {//找到空簇,将当前簇的下一簇放到找到空簇的下一簇
       temp = Get_Next_Cluster_From_Current_Cluster(Cluster);
       buf[ThisFATEntOffset] = (u8)(temp & 0xff);  
       buf[ThisFATEntOffset + 1] = (u8)((temp >> 8) & 0xff);
       //回写FAT1
	   write_flash_sector(buf,ThisFAT1SecNum);  
       temp = ThisFAT2SecNum;
       //回写其它FAT2及所有的FAT表
	   for(i = 1;i < BPB.numbers_of_FAT;i++)
         {
          write_flash_sector(buf,temp);
          temp +=  BPB.sectors_per_FAT;
         }  
       temp = Get_Next_Cluster_From_Current_Cluster(Cluster);
       //将当前簇的下一簇填写指定找到的空簇
	   ThisFATEntOffset = Cluster * 2;
       //计算当前簇所在扇区
	   ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector 
                   + (ThisFATEntOffset / BPB.bytes_per_sector);
       
	    //计算当前簇所在扇区的偏移量
	   ThisFATEntOffset = ThisFATEntOffset % BPB.bytes_per_sector;
       ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT; 
       read_flash_sector(buf,ThisFAT1SecNum);
       buf[ThisFATEntOffset] = (u8)(EMPTY_CLUSTER & 0xff);//Add to cluster chain
       buf[ThisFATEntOffset + 1] = (u8)((EMPTY_CLUSTER >> 8) & 0xff); 
       //回写FAT1
	   write_flash_sector(buf,ThisFAT1SecNum);  
       //回写其它FAT2及所有的FAT表
	   temp = ThisFAT2SecNum;
       for(i = 1;i < BPB.numbers_of_FAT;i++)  //update backup FAT2,etc..
         {          
		   read_flash_sector(buf,temp);
           buf[ThisFATEntOffset] = (u8)(EMPTY_CLUSTER & 0xff);//Add to cluster chain
           buf[ThisFATEntOffset + 1] = (u8)((EMPTY_CLUSTER >> 8) & 0xff); 
           write_flash_sector(buf,temp);
           temp +=  BPB.sectors_per_FAT;
         } 
	    //将空簇的数据清空
	   for(i = 0;i< 512;i++)
		   buf[i] = 0;
       ThisFAT1SecNum = FirstSectorofCluster(EMPTY_CLUSTER);
	   for(i = 0;i < BPB.sector_per_cluster;i++)
           write_flash_sector(buf,ThisFAT1SecNum + i);
       *Added_Cluster = EMPTY_CLUSTER;                  
       return(SUCC);
      }
     else
      {
        ThisFATEntOffset += 2;
        EMPTY_CLUSTER ++;
		//超出最大簇号,查找失败
        if( EMPTY_CLUSTER == (CORE.CountofClusters + 2))
         {
          return(FAIL);
         } 
      }
   }
  ThisFAT1SecNum ++;
  ThisFAT2SecNum ++;
  }while(1);     
}

/*===============================================================================
函数
从FAT中分配一个空簇
入口:cluster--被分配的簇
出口: SUCC,FAIL
===============================================================================*/ 
u8 Allocate_An_Empty_cluster(u32 * cluster,u8 * buf)
{
  u32 temp,EMPTY_CLUSTER,ThisFAT1SecNum,ThisFATEntOffset,ThisFAT2SecNum;
  u16 i; 

  //从起始FAT表的起始扇区,找空簇以完成分配
  EMPTY_CLUSTER = 0;
  ThisFAT1SecNum = CORE.relative_sector + BPB.reserved_sector;
  ThisFAT2SecNum = ThisFAT1SecNum + BPB.sectors_per_FAT;
  do{      
  ThisFATEntOffset = 0; 
  read_flash_sector(buf,ThisFAT1SecNum);   
  for(i = 0;i < 256;i++)
   {
     if(buf[ThisFATEntOffset] == 0 && buf[ThisFATEntOffset + 1] == 0)
      {//找到空簇,设置空簇为0XFFFF,即占用状态
       buf[ThisFATEntOffset] = 0xff;   
       buf[ThisFATEntOffset + 1] = 0xff;
       //回写FAT1
	   write_flash_sector(buf,ThisFAT1SecNum);  
       //回写其它FAT2及所有的FAT表
	   temp = ThisFAT2SecNum;
       for(i = 1;i < BPB.numbers_of_FAT;i++)  //update backup FAT2,etc..
         {
          write_flash_sector(buf,temp);
          temp +=  BPB.sectors_per_FAT;
         }  
	   //将空簇的数据清空
	   for(i = 0;i< 512;i++)
		   buf[i] = 0;
       ThisFAT1SecNum = FirstSectorofCluster(EMPTY_CLUSTER);
	   for(i = 0; i < BPB.sector_per_cluster;i++)
           write_flash_sector(buf,ThisFAT1SecNum + i);
       *cluster = EMPTY_CLUSTER;                  
       return(SUCC);
      }
     else
      {
        ThisFATEntOffset += 2;
        EMPTY_CLUSTER ++; 
		//超出最大簇号,查找失败
        if( EMPTY_CLUSTER == (CORE.CountofClusters + 2))
         {
          return(FAIL);
         } 
      }
   }
  ThisFAT1SecNum ++;
  ThisFAT2SecNum ++;
  }while(1);     

}

  
/*===============================================================================
函数(CORE_INIT_2)
从root sector BPB计算FirstDataSector,FirstRootDirSecNum等等
入口:无
出口: 无

⌨️ 快捷键说明

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