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