📄 fat.c
字号:
}
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 + -