📄 fat.c
字号:
CORE.ClusterNum = CORE.ClusterOfDirectoryEntry;
CORE.SectorNum = FirstSectorofCluster(CORE.ClusterNum);
}
CORE.offset = 0;
read_flash_sector(buf,CORE.SectorNum);
while(1)
{
SectorNum_LOCAL = CORE.SectorNum; // 保存当前ENTRY的首位置
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)//空ENTRY
{
Empty_Entry_Space_Count++;
//直到找到指定数量的空ENTRY
if(Empty_Entry_Space_Count >= Entry_Resuested_QTY)
{
found_flag = 1;
break;
}
}
else
break;
if(CORE_offset_add_32_With_EMPTY_CLUSTER_ALLOCATION(buf) == FAIL)
return(FAIL);
}while(1);
if(found_flag)//找到指定数量的空ENTRY
{
CORE.SectorNum = SectorNum_LOCAL; //置空ENTRY的首位置
CORE.ClusterNum = ClusterNum_LOCAL;
CORE.offset = Offset_LOCAL;
break;
}
else if(CORE_offset_add_32_With_EMPTY_CLUSTER_ALLOCATION(buf) == FAIL)
return(FAIL);
}
return(SUCC);
}
/*===============================================================================
函数
填写一个LFN directory entry
入口:u8 * Directory_Entry_buf,u8 * Entry_Name,u8 LFN_record_FLAG
u8 Entry_Name,u8 checksum
出口:SUCC,FAIL
===============================================================================*/
static u8 Fill_LFN_Directory_Entry(u8 * Directory_Entry_buf,u8 * Entry_Name,u8 LFN_record_FLAG,u8 checksum)
{
u8 i;
i = LengthofString(Entry_Name);
if(i < 12)
{
do{ //填写空白空间
i++;
if(i >= 13)
break;
Entry_Name[i] = 0xff;
}while(1);
}
Directory_Entry_buf[0] = LFN_record_FLAG;;
//填写前5个字节
for(i = 0;i < 5;i++)
{
Directory_Entry_buf[1 + i * 2] = Entry_Name[i];
if(Entry_Name[i] != 0xff)
Directory_Entry_buf[2 + i * 2] = 0;
else
Directory_Entry_buf[2 + i * 2] = 0xff;
}
Directory_Entry_buf[11] = ATTR_LONG_NAME; //0x0F, impossible file attribute used as signature
Directory_Entry_buf[12] = 0; //Reserved (?). Set to 0x00
Directory_Entry_buf[13] = checksum;//填写校验和
//填写中间6个字节
for(i = 0;i < 6;i++)
{
Directory_Entry_buf[14 + i * 2] = Entry_Name[5 + i];
if(Entry_Name[5 + i] != 0xff)
Directory_Entry_buf[15 + i * 2] = 0;
else
Directory_Entry_buf[15 + i * 2] = 0xff;
}
Directory_Entry_buf[26] = 0; //First cluster number (always 0x0000 for long filename records)
Directory_Entry_buf[27] = 0;
//填写2个字节
for(i = 0;i < 2;i++)
{
Directory_Entry_buf[28 + i * 2] = Entry_Name[11 + i];
if(Entry_Name[11 + i] != 0xff)
Directory_Entry_buf[29 + i * 2] = 0;
else
Directory_Entry_buf[29 + i * 2] = 0xff;
}
return(SUCC);
}
/*===============================================================================
函数
填写短文件directory entry
入口:u8 * Directory_Entry_buf,u8 * Entry_Name,u32 first_cluster,
u32 FileSize,u8 attr
出口:SUCC,FAIL
===============================================================================*/
static u8 Fill_SFN_Directory_Entry(u8 * Directory_Entry_buf,u8 * Entry_Name,u32 first_cluster,u32 FileSize,u8 attr)
{
u8 i,flag,j;
for(i = 0;i < 11;i++)
Directory_Entry_buf[i] = 0x20;
i = 0;
j = 0;
flag = FILE_NAME;
do{ //Directory_Entry分离取得Shortfile Entry name and file extension
if( ( * Entry_Name) != 0)
{
if( flag == FILE_NAME)
{
if(*Entry_Name == '.')//遇到'.',转入填写File extension
{
flag = FILE_EXTENSION;
Entry_Name++;
}
else
{
Directory_Entry_buf[i] = *Entry_Name;//填写Entry Name
i++;
Entry_Name++;
if( i > 8 )
break;
}
}
else if( flag == FILE_EXTENSION)
{
if( j >= 3 )
break;
Directory_Entry_buf[8+j] = *Entry_Name;//填写File extension
j++;
Entry_Name++;
}
}
else
break;
}while(1);
Directory_Entry_buf[11] = attr;
Directory_Entry_buf[12] = 0;
Directory_Entry_buf[26] = (u8)(first_cluster & 0xff); //填写首簇号
Directory_Entry_buf[27] = (u8)((first_cluster >> 8) & 0xff);
Directory_Entry_buf[28] = (u8)(FileSize & 0xff);////填写文件长度
Directory_Entry_buf[29] = (u8)((FileSize >> 8) & 0xff);
Directory_Entry_buf[30] = (u8)((FileSize >> 16) & 0xff);
Directory_Entry_buf[31] = (u8)((FileSize >> 24) & 0xff);
return(SUCC);
}
/*===============================================================================
函数
把Longfilename Directory Entry转换为short filename
入口:Directory_Entry:Directory_Entry name,attr:attr of Directory_Entry
出口:SUCC,FAIL
===============================================================================*/
static u8 LFN_convert_to_SFN(u8 * Directory_Entry,u8 * SFN_Directory_Entry_buf)
{
u8 i,flag,j;
for(i = 0;i < 11;i++)
SFN_Directory_Entry_buf[i] = 0x20; //初始化DIRECTORY ENTRY
i = 0;
j = 0;
flag = FILE_NAME;
do{
if( ( * Directory_Entry) != 0)
{
if( flag == FILE_NAME)
{
if(*Directory_Entry == '.')//遇到'.',转入填写File extension
{
flag = FILE_EXTENSION;
Directory_Entry++;
}
else
{
SFN_Directory_Entry_buf[i] = *Directory_Entry;//填写Entry Name
i++;
if(i >= 6)
{
SFN_Directory_Entry_buf[i] = '~';
SFN_Directory_Entry_buf[i+1] = '1';
do{
if(*Directory_Entry == '.' || ( * Directory_Entry) == 0 )
{
flag = FILE_EXTENSION;
break;
}
else
Directory_Entry++;
}while(1);
}
Directory_Entry++;
}
}
else if( flag == FILE_EXTENSION)
{
if( j >= 3 )
return(FAIL);//填写File extension
SFN_Directory_Entry_buf[8+j] = *Directory_Entry;
j++;
Directory_Entry++;
}
}
else
return(SUCC);
}while(1);
}
/*===============================================================================
函数
将写Longfilename Directory Entry入磁盘
入口:Directory_Entry:Directory_Entry name,attr:attr of Directory_Entry
出口:SUCC,FAIL
===============================================================================*/
static u8 Write_LongFileName_Entry(u8 * Directory_Entry,u8 attr,u32 first_cluster,u8 * buf,u32 FileSize)
{
u16 len;
u8 i,checksum;
u8 Directory_Entry_buf[32];
u8 SN,LFN_record_FLAG;
//计算需要的Directory_Entry空间,每个Directory_Entry空间为32个字节,计算结果放在len中
len = LengthofString(Directory_Entry) / 13;
if(LengthofString(Directory_Entry) % 13)
len++;
SN = len;
//从long-filename directory entry处理得其对应的short-filename directory entry
LFN_convert_to_SFN(Directory_Entry,Directory_Entry_buf);
//计算short-filename directory entry校验和
checksum = calculate_checksum_longfilenameentry(Directory_Entry_buf);
//处理last long-filename directory entry for file
read_flash_sector(buf,CORE.SectorNum);
LFN_record_FLAG = SN | (u8)Last_LFN_Record;
Fill_LFN_Directory_Entry(buf + CORE.offset,Directory_Entry + (len - 1) * 13,LFN_record_FLAG,checksum);
len--;
write_flash_sector(buf,CORE.SectorNum);
CORE_offset_add_32(buf);
LFN_record_FLAG = SN;
//处理其它LFN directory entry
//do{
while(len){
SN--;
Directory_Entry[len * 13] = 0;
Fill_LFN_Directory_Entry(buf + CORE.offset,Directory_Entry + (len - 1) * 13,SN,checksum);
len--;
write_flash_sector(buf,CORE.SectorNum);
CORE_offset_add_32(buf);
}
//处理LFN 相应的short-filename directory entry
Directory_Entry_buf[11] = attr;
Directory_Entry_buf[12] = 0;
Directory_Entry_buf[26] = (u8)(first_cluster & 0xff); //填写首簇号
Directory_Entry_buf[27] = (u8)((first_cluster >> 8) & 0xff);
Directory_Entry_buf[28] = (u8)(FileSize & 0xff);////填写文件长度
Directory_Entry_buf[29] = (u8)((FileSize >> 8) & 0xff);
Directory_Entry_buf[30] = (u8)((FileSize >> 16) & 0xff);
Directory_Entry_buf[31] = (u8)((FileSize >> 24) & 0xff);
for(i = 0;i < 32;i++)
{
buf[CORE.offset + i] = Directory_Entry_buf[i];
}
write_flash_sector(buf,CORE.SectorNum);
return(SUCC);
}
/*===============================================================================
函数
添加Directory_Entry至目录
入口:Directory_Entry-
出口:SUCC,FAIL
===============================================================================*/
static u8 Add_A_Directory_Entry_(u8 * Directory_Entry,u8 attr,u32 first_cluster,u32 FileSize)
{
u16 len;
u8 buf[512];
u8 Directory_Entry_buf[32];
u8 temp,i;//,j;
if(attr & ATTR_DIRECTORY)
{//给新建的directory分配簇号再写入默认两个目录,“.”和“..”
u32 sector_local;
if( Allocate_An_Empty_cluster(&first_cluster,buf)== FAIL)
return(FAIL);
//初始化默认两个目录,目录名分别取名为“.”和“..”
sector_local = FirstSectorofCluster(first_cluster);
for(i = 0;i < 11;i++)
buf[i] = 0x20;
buf[0] = '.';//填写目录名“.”
buf[11] = attr;
buf[12] = 0;
buf[26] = (u8)(first_cluster & 0xff); //填写当前目录簇号
buf[27] = (u8)((first_cluster >> 8) & 0xff);
buf[28] = 0;////填写文件长度
buf[29] = 0;
buf[30] = 0;
buf[31] = 0;
for(i = 0;i < 11;i++)
buf[i + 32] = 0x20;
buf[32] = '.'; //填写目录名“..”
buf[33] = '.';
buf[32+11] = attr;
buf[32+12] = 0;
buf[32+26] = (u8)(CORE.ClusterNum & 0xff); //填写当前目录父目录的首簇号
buf[32+27] = (u8)((CORE.ClusterNum >> 8) & 0xff);
buf[32+28] = 0;////填写文件长度
buf[32+29] = 0;
buf[32+30] = 0;
buf[32+31] = 0;
buf[64] = 0;
write_flash_sector(buf,sector_local);
}
//计算Directory_Entry需要多少个空间,Directory_Entry每个空间为32个字节,计算结果放在len中
len = LengthofString(Directory_Entry) / 13;
if(LengthofString(Directory_Entry) % 13)
len++;
if(len > 1)
len++;
if(len == 1)
{
u8 count;
count = 0;
do{
if(Directory_Entry[count] == 0 || Directory_Entry[count] == '.')
break;
count++;
}while(1);
if(count > 8)
len = 2;
}
//寻找指定数量的空间
if(Seek_Space_to_Write_Directory_Entry(len,buf) == SUCC)
{
if(len == 1) //写短文件名
{
UPCASE(Directory_Entry);
Fill_SFN_Directory_Entry(Directory_Entry_buf,Directory_Entry, first_cluster,FileSize,attr);
read_flash_sector(buf,CORE.SectorNum);
for(temp = 0;temp < 32;temp++)
{
buf[CORE.offset + temp] = Directory_Entry_buf[temp];
}
write_flash_sector(buf,CORE.SectorNum);
return(SUCC);
}
else//写长文件名
{
return(Write_LongFileName_Entry(Directory_Entry,attr,first_cluster,buf,FileSize));
}
}
else
return(FAIL);
}
/*===============================================================================
函数
建立文件
入口:无
出口:无
===============================================================================*/
#if complie_create_file
u8 create_file(u8 * filename)
{
u16 len;
u16 temp;
u8 buf[260],status;
stringcpy(filename,buf);
CORE.FullPathType = FilePath;
if(FullPathToSectorCluster(filename) != SUCC) //检查文件是否已经存在
{ //文件不存在,才可以建文件
len = LengthofString(buf);
//从文件名中分离路径
temp = len - 1;
do{
if(buf[temp] =='\\')
{
buf[temp] = 0;
temp++;
break;
}
if(!temp)
break;
temp--;
}while(1);
CORE.FullPathType = DirectoryPath;
if(!temp)
{ //相
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -