📄 fat.c
字号:
if(CORE_offset_add_32_With_EMPTY_CLUSTER_ALLOCATION(buf) == FAIL)
return(FAIL);
}while(1);
if(found_flag)
{
CORE.SectorNum = SectorNum_LOCAL;
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);
//////printf("i = %d",i);
if(i < 12)
{
do{ //pad the remnant space
i++;
if(i >= 13)
break;
Entry_Name[i] = 0xff;
}while(1);
}
Directory_Entry_buf[0] = LFN_record_FLAG;;
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;
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;
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);
}
/*
===============================================================================
函数
完成填写一个SFN 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;
////printf("Entry_Name %s",Entry_Name);
flag = FILE_NAME;
do{ //Directory_Entry分离取得Shortfile Entry name and file extension
if( ( * Entry_Name) != 0)
{
if( flag == FILE_NAME)
{
if(*Entry_Name == '.')
{
flag = FILE_EXTENSION;
Entry_Name++;
}
else
{
Directory_Entry_buf[i] = *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;
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;
i = 0;
j = 0;
flag = FILE_NAME;
do{ //Directory_Entry分离取得Shortfile Entry name and file extension
if( ( * Directory_Entry) != 0)
{
if( flag == FILE_NAME)
{
if(*Directory_Entry == '.')
{
flag = FILE_EXTENSION;
Directory_Entry++;
}
else
{
SFN_Directory_Entry_buf[i] = *Directory_Entry;
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);
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++;
//if(len == 1)
// len = 2;
////printf("len =%d",len);
SN = len; //sequence number reset to 0
//从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);
//////printf("%s",Directory_Entry + (len - 1) * 13);
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);
//if(!len )
// break;
}
//}while(1);
////printf("CORE.SectorNum %ld CORE.ClusterNum %ld CORE.offset %ld",
//CORE.SectorNum,CORE.ClusterNum,CORE.offset);
//处理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++)
{ ////////printf(" %x ",buf[CORE.offset + temp]);
buf[CORE.offset + i] = Directory_Entry_buf[i];
}
write_flash_sector(buf,CORE.SectorNum);
//CORE_offset_add_32(buf);
////printf("kkk");
return(SUCC);
}
/*
===============================================================================
函数
添加一个Directory_Entry到目录
入口:Directory_Entry:Directory_Entry name,attr:attr of 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;
//给新建directory分配首簇及写入默认的两个目录,“.”和“..”
if(attr & ATTR_DIRECTORY)
{
u32 sector_local;
if( Allocate_An_Empty_cluster(&first_cluster,buf)== FAIL)
return(FAIL);
//////printf("first_cluster = %d" ,first_cluster);
//初始化两个默认目录,目录名分别命名为“.”和“..”
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)
{
//////printf("CORE.SectorNum %ld CORE.ClusterNum %ld CORE.offset %ld",
//CORE.SectorNum,CORE.ClusterNum,CORE.offset);
if(len == 1) //短文件名写入
{
////////printf("%s %s ",Directory_Entry_buf,Directory_Entry_buf+8);
//printf("Directory_Entry %s",Directory_Entry);
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//长文件名写入
{ //////printf("Tony Tony Tony %s",Directory_Entry);
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;
////printf("%s",filename);
stringcpy(filename,buf);
CORE.FullPathType = FilePath;
if(FullPathToSectorCluster(filename) != SUCC) //check File is already exist?
{
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)
{
if(FullPathToSectorCluster(CORE.current_folder)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -