📄 fat.c
字号:
return F_OK;
}
/*==============================================================================
函数名: fat_offset_sector
-------------------------------------------------------------------------------
参数:偏移扇区数
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:从当前位置偏移参数要求的扇区数
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 fat_offset_sector(UINT32 cc)
{
while(cc)
{
fat_count_offset_sector++;
if (fat_count_offset_sector == fat_sec_perclus)
{
fat_count_offset_sector =0;
fat_count_offset_cluster++; /*连续簇的下一个簇*/
if (chain[fat_chain_index].number ==fat_count_offset_cluster)
{
fat_count_offset_cluster =0;
fat_chain_index++;
}
if(fat_chain_index >fat_last_chain_index) /*不能超过簇,文件剩余扇区数不计*/
{
return PARAMETER_CMD_ERR;
}
}
cc--;
#ifdef FAT_DEBUG
com_prints("fat_chain_index:",0);
com_send_arry(&fat_chain_index,1,1);
com_prints("fat_count_offset_cluster:",0);
com_send_arry(&fat_count_offset_cluster,1,1);
com_prints("fat_count_offset_sector:",0);
com_send_arry(&fat_count_offset_sector,1,1);
com_send_arry(&cc,2,1);
#endif
}
#ifdef FAT_DEBUG
com_prints("fat_chain_index:",0);
com_send_arry(&fat_chain_index,1,1);
com_prints("fat_count_offset_cluster:",0);
com_send_arry(&fat_count_offset_cluster,1,1);
com_prints("fat_count_offset_sector:",0);
com_send_arry(&fat_count_offset_sector,1,1);
#endif
return F_OK;
}
/*==============================================================================
函数名: fat_read_sector
-------------------------------------------------------------------------------
参数:BOOL mode(分为读目录项数据和读文件数据) UINT8 index是在磁盘缓区的偏移*512
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:根据构建的簇链表,读扇区数据到缓冲区
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 fat_read_sector (BOOL mode, UINT8 index)
{
UINT8 i;
UINT32 next_cluster;
if((mode==F_OPEN_DIR))
{ /*读目录FAT32与12/16在根目录数有区别*/
if((fat_type_sign==F_TYPE_FAT32)||(fat_dir_now_l!=1))
{
next_cluster =chain[fat_chain_index].cluster + fat_count_offset_cluster-2;
if (fat_count_offset_sector ==fat_sec_perclus) /*读完一簇或刚进入*/
{ /*此连续的簇用完,查找下一个连续的簇开始*/
fat_count_offset_sector =0;
fat_count_offset_cluster++;
if (chain[fat_chain_index].number ==fat_count_offset_cluster)
{
fat_chain_index++;
fat_count_offset_cluster = 0;
}
next_cluster =chain[fat_chain_index].cluster + fat_count_offset_cluster-2;
}
fat_current_sect = fat_data_start_sector + fat_count_offset_sector
+ ((UINT32)(next_cluster) * fat_sec_perclus);
fat_count_offset_sector++;
}
else
{
fat_current_sect++; /*在FAT12/16的根目录下*/
}
#ifdef FAT_DEBUG
com_prints("fat_chain_index:",0);
com_send_arry(&fat_chain_index,1,1);
com_prints("fat_current_sect:",0);
com_send_arry(&fat_current_sect,4,1);
#endif
i=hard_read_sector(fat_current_sect); /*读下一个扇区*/
if(i==F_OK)
return F_OK;
else
return READ_DATA_ERR;
}
else /*打开文件模式*/
{
UINT8 i;
UINT8 offset; /*用在文件缓冲区里的偏移*/
UINT16 temp16;
UINT32 temp32;
/*计算还有多少个连续的扇区*/
if(fat_chain_index >fat_last_chain_index)
{
fat_cmd.read.sector =0;
return F_OK;
}
offset =0;
while(index)
{
if(fat_chain_index ==fat_last_chain_index) /*到最后一个连续簇链*/
{
i =((fat_file_length + 511) / 512) % fat_sec_perclus;
if(i ==0)
i=fat_sec_perclus; /*剩余簇全部为文件数据*/
i =fat_sec_perclus -i; /*计算尾部无效扇区*/
#ifdef FAT_DEBUG
com_prints("i:",0);
com_send_arry(&i,1,1);
#endif
temp16 =(chain[fat_chain_index].number -fat_count_offset_cluster) *fat_sec_perclus
-fat_count_offset_sector -i; /*剩余连续扇区数*/
#ifdef FAT_DEBUG
com_prints("temp16:",0);
com_send_arry(&temp16,2,1);
com_prints("fat_count_offset_sector:",0);
com_send_arry(&fat_count_offset_sector,1,1);
#endif
if((temp16) < (UINT16)index)
{
index =(UINT8)temp16;
fat_cmd.read.sector =index; /*计算实际有效扇区数*/
if(index ==0)
return F_OK;
}
}
else
{
temp16 =(chain[fat_chain_index].number -fat_count_offset_cluster) *fat_sec_perclus
-fat_count_offset_sector; /*剩余连续扇区数*/
}
#ifdef FAT_DEBUG
com_prints("temp16:",0);
com_send_arry(&temp16,2,1);
com_prints("index:",0);
com_send_arry(&index,1,1);
#endif
if((temp16)>=(UINT16)index)
{
temp32 =fat_data_start_sector + (chain[fat_chain_index].cluster + fat_count_offset_cluster - 2)
*fat_sec_perclus +fat_count_offset_sector;
i =hard_read_file_sector(temp32,index,offset);
if(i!=F_OK)
return READ_DATA_ERR;
fat_current_sect =temp32 +index -1;
fat_offset_sector(index); /*偏移扇区*/
index =0;
}
else /*剩余连续扇区较少*/
{
i =hard_read_file_sector((fat_data_start_sector +(chain[fat_chain_index].cluster
+ fat_count_offset_cluster - 2) *fat_sec_perclus +fat_count_offset_sector),(UINT8)temp16,offset);
if(i!=F_OK)
return READ_DATA_ERR;
fat_offset_sector((UINT8)temp16);
offset +=(UINT8)temp16;
index -=(UINT8)temp16; /*还有多少个扇区没有读*/
}
#ifdef FAT_DEBUG
com_prints("fat_chain_index:",0);
com_send_arry(&fat_chain_index,1,1);
com_prints("fat_count_offset_cluster:",0);
com_send_arry(&fat_count_offset_cluster,1,1);
com_prints("fat_count_offset_sector:",0);
com_send_arry(&fat_count_offset_sector,1,1);
#endif
}
return F_OK;
}
}
/*==============================================================================
函数名: fat_write_sector
-------------------------------------------------------------------------------
参数:index为扇区数
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:根据构建的簇链表,写扇区数据到缓冲区
-------------------------------------------------------------------------------
==============================================================================*/
#if F_EN_WRITE ==1
STATIC UINT8 fat_write_sector (UINT8 index)
{
UINT8 i;
UINT8 offset;
UINT16 temp16;
offset =0;
while(index)
{
if(fat_chain_index > fat_last_chain_index) /*超出文件范围*/
{
temp16 =0;
}
else
{
temp16 =(chain[fat_chain_index].number -fat_count_offset_cluster) *fat_sec_perclus
-fat_count_offset_sector; /*计算当前有多少个连续的扇区*/
}
if((temp16) >= (UINT16)index)
{
i =hard_write_file_sector((fat_data_start_sector + (chain[fat_chain_index].cluster
+ fat_count_offset_cluster - 2)*fat_sec_perclus +fat_count_offset_sector),index,offset);
if(i!=F_OK)
return WRITE_DATA_ERR;
i =fat_offset_sector(index); /*偏移扇区*/
if(i !=F_OK)
{
#if F_EN_ADD_EDN ==1
if(fat_cmd.write.sector ==0) /*所有扇区数据写完*/
return F_OK;
i=fat_get_space(F_CONTI_MODE); /*继续申请磁盘空间*/
if(i !=F_OK)
return i;
i=fat_update(F_CONTI_MODE); /*更新此空间的FAT*/
if(i !=F_OK)
return i;
fat_offset_sector(fat_sec_perclus); /*偏移文件结束簇*/
fat_add_bit =F_TRUE; /*在文件末尾添加过数据*/
#else
return NO_DEF_ADD_ERR;
#endif
}
index =0;
}
else /*剩余连续扇区较少*/
{
#ifdef FAT_DEBUG
com_prints("index: ",0);
com_send_arry(&index,1,1);
com_prints("temp16: ",0);
com_send_arry(&temp16,2,1);
#endif
if(temp16 !=0)
{
i =hard_write_file_sector((fat_data_start_sector +(chain[fat_chain_index].cluster
+ fat_count_offset_cluster - 2) *fat_sec_perclus +fat_count_offset_sector),(UINT8)temp16,offset);
if(i!=F_OK)
return READ_DATA_ERR;
}
index -=(UINT8)temp16; /*还有多少个扇区没有写*/
offset +=(UINT8)temp16; /*改写文件缓冲区里偏移*/
i =fat_offset_sector((UINT8)temp16);
if((i !=F_OK)||(temp16 ==0)) /*等于0 说明文件偏移到结尾*/
{
#if F_EN_ADD_EDN ==1
fat_cmd.write.sector +=index; /*申请扇区空间加上剩余未写的*/
if(fat_cmd.write.sector ==0) /*所有扇区数据写完*/
return F_OK;
i=fat_get_space(F_CONTI_MODE); /*继续申请磁盘空间*/
if(i !=F_OK)
return i;
fat_cmd.write.sector -=index;
i=fat_update(F_CONTI_MODE); /*更新此空间的FAT*/
if(i !=F_OK)
return i;
fat_offset_sector(fat_sec_perclus); /*偏移文件结束簇*/
fat_add_bit =F_TRUE; /*在文件末尾添加过数据*/
#else
return NO_DEF_ADD_ERR;
#endif
}
}
}
return F_OK;
}
#endif
/*==============================================================================
函数名: ini_chain_arry
-------------------------------------------------------------------------------
参数:mode分为是否初始化变量
-------------------------------------------------------------------------------
函数返回:此数组包含的总扇区数
-------------------------------------------------------------------------------
函数作用:构建完簇数组后,初始化各变量
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT32 ini_chain_arry(BOOL mode)
{
UINT8 i;
UINT32 temp32=0;
for (i = 0; i <= fat_last_chain_index; i++)
{
temp32 += chain[i].number; /*计算当前目录有多少个簇*/
}
if(mode ==F_TRUE)
{
fat_chain_index=0; /*指向数组开始*/
fat_count_offset_cluster=0; /*指向第一个连续簇开始*/
fat_count_offset_sector=0; /*指向此簇的第一个扇区*/
}
temp32 *=fat_sec_perclus; /*得到此目录的总扇区数*/
return temp32;
}
#if F_EN_LONG_NAME ==1
/*==============================================================================
函数名: chk_file_name_sum
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -