📄 fat.c
字号:
pfi->FileCurOffset++;
}
}
else
{
len=0;
}
return len;
}
/**************************************************************************
- 功能描述:从文件某一位置读取一定长度的数据,由pfun所指向的函数来处理
- 隶属模块:FAT文件系统模块
- 函数属性:外部,使用户使用
- 参数说明:pfi:FileInfoStruct类型的结构体指针,用于装载文件参数信息,文件
读取的过程中,此结构体中的相关参数会更新,比如文件的当前偏移量、
文件的当前扇区,文件的当前簇等等
offset:要定位的偏移量,要小于文件的大小
len:要读取的数据的长度,如果len+offset大于文件的大小,则实际读
取的数据量是从offset开始到文件结束
pfun:对读取的数据的处理函数,pfun指向处理函数,这样可以灵活的
配置数据如何去处理,比如是放在缓冲区中,还是把数据通过串口发送
出去,只需要pfun去指向相应的处理函数可以了
- 返回说明:读取到的实际的数据长度,如果读取失败,比如指定的偏移量大于了文件
大小,则返回0
- 注:在读取一个文件的数据前,必须先将该文件用FAT32_Open_File打开
**************************************************************************/
/*
UINT32 FAT32_Read_FileX(struct FileInfoStruct *pfi,UINT32 offset,UINT32 len,void (*pfun)(UINT8))
{
UINT32 i,j,k,temp;
UINT32 counter=0;
if(offset<pfi->FileSize)
{
if(offset+len>pfi->FileSize) len=pfi->FileSize-offset;
FAT32_Seek_File(pfi,offset);
FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
for(i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(FAT32_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurOffset++;
}
if(pfi->FileCurSector-(SOC(pfi->FileCurCluster))!=(pArg->SectorsPerClust-1))
{
for(j=pfi->FileCurSector+1;j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(FAT32_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurOffset++;
}
}
}
temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
for(k=0;k<temp;k++)
{
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
for(j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(FAT32_Buffer[i]);
counter++;
pfi->FileCurOffset++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
}
}
}
pfi->FileCurCluster=FAT32_GetNextCluster(pfi->FileCurCluster);
temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
pfi->FileCurSector=(SOC(pfi->FileCurCluster));
for(j=(SOC(pfi->FileCurCluster));j<temp;j++)
{
FAT32_ReadSector(j,FAT32_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(FAT32_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
pfi->FileCurSector=j;
FAT32_ReadSector(pfi->FileCurSector,FAT32_Buffer);
temp=len-counter;
for(i=0;i<temp;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(FAT32_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
else
{
len=0;
}
return len;
}
*/
/**************************************************************************
- 功能描述:寻找可用的空闲簇
- 隶属模块:FAT文件系统模块
- 函数属性:内部
- 参数说明:无
- 返回说明:如果找到了空闲簇,返回空闲簇的簇号,否则返回0
- 注:寻找空闲簇是创建目录/文件以及向文件写入数据的基础,它如果能很快的寻
找到空闲簇,那么创建目录/文件以及向文件写入数据这些操作也会比较快。
所以我们绝不会从最开始的簇依次去寻找,而是使用了二分搜索的算法,以达
到较好的效果。如果空闲簇没有找到,很有可能就说明存储设备已经没有空间
了
**************************************************************************/
/*
UINT32 FAT32_Find_Free_Clust(unsigned char flag)
{
UINT32 iClu,iSec;
struct FAT32_FAT *pFAT;
for(iSec=pArg->FirstFATSector+temp_last_cluster/128;iSec<pArg->FirstFATSector+pArg->FATsectors;iSec++)
{
FAT32_ReadSector(iSec,FAT32_Buffer);
pFAT=(struct FAT32_FAT *)FAT32_Buffer;
for(iClu=0;iClu<pArg->BytesPerSector/4;iClu++)
{
if(LE2BE((UINT8 *)(&((pFAT->Items))[iClu]),4)==0)
{
if(!flag)
{
FAT32_Update_FSInfo_Free_Clu(0);
temp_last_cluster=128*(iSec-pArg->FirstFATSector)+iClu;
return temp_last_cluster;
}
else
{
FAT32_Update_FSInfo_Last_Clu(128*(iSec-pArg->FirstFATSector)+iClu);
return 128*(iSec-pArg->FirstFATSector)+iClu;
}
}
}
}
return 0;
}
*/
/**************************************************************************
- 功能描述:填充文件/目录项
- 隶属模块:FAT文件系统模块
- 函数属性:内部
- 参数说明:prec:指向一个direntry类型的结构体,它的结构就是FAT32中文件/
目录项的结构
name:文件或目录的名称
is_dir:指示这个文件/目录项是文件还是目录,分别用来实现文件、
目录的创建 1表示创建目录 0表示创建文件
- 返回说明:无
- 注:这里创建文件或目录的方法是,先将文件或目录的信息填充到一个结构体中,
然后再将这个结构体的数据写入到存储设备的相应的扇区的相应位置上去,这
样就完成了文件或目录的创建。
在填充文件或目录的信息时,文件或目录的首簇并没有填进去,而是全0
**************************************************************************/
/*
void Fill_Rec_Inf(struct direntry *prec,INT8 *name,UINT8 is_dir,UINT8 *ptd)
{
UINT8 i=0,len=0;
UINT16 temp;
if(is_dir)
{
len=strlen(name);
if(len>8)
{
for(i=0;i<6;i++)
{
(prec->deName)[i]=L2U(name[i]);
}
(prec->deName)[6]='~';
(prec->deName)[7]='1';
}
else
{
for(i=0;i<len;i++)
{
(prec->deName)[i]=L2U(name[i]);
}
for(;i<8;i++)
{
(prec->deName)[i]=' ';
}
}
for(i=0;i<3;i++)
{
(prec->deExtension)[i]=' ';
}
}
else
{
while(name[len]!='.' && name[len]!=0) len++;
if(len>8)
{
for(i=0;i<6;i++)
{
(prec->deName)[i]=L2U(name[i]);
}
(prec->deName)[6]='~';
(prec->deName)[7]='1';
}
else
{
for(i=0;i<len;i++)
{
(prec->deName)[i]=L2U(name[i]);
}
for(;i<8;i++)
{
(prec->deName)[i]=' ';
}
}
if(name[len]==0)
{
for(i=0;i<3;i++)
{
(prec->deExtension)[i]=' ';
}
}
else
{
for(i=0;i<3;i++)
{
(prec->deExtension)[i]=' ';
}
len++;
i=0;
while(name[len]!=0)
{
(prec->deExtension)[i++]=L2U(name[len]);
len++;
}
}
}
if(is_dir)
(prec->deAttributes)=0x10;
else
(prec->deAttributes)=0x20;
temp=MAKE_FILE_TIME(ptd[3],ptd[4],ptd[5]);
(prec->deCTime)[0]=temp;
(prec->deCTime)[1]=temp>>8;
temp=MAKE_FILE_DATE(ptd[0],ptd[1],ptd[2]);
(prec->deCDate)[0]=temp;
(prec->deCDate)[1]=temp>>8;
(prec->deLowerCase)=0;
(prec->deHighClust)[0]=0;
(prec->deHighClust)[1]=0;
(prec->deLowCluster)[0]=0;
(prec->deLowCluster)[1]=0;
for(i=0;i<4;i++)
{
(prec->deFileSize)[i]=0;
}
}
*/
/**************************************************************************
- 功能描述:更新FAT表
- 隶属模块:FAT文件系统模块
- 函数属性:内部
- 参数说明:cluster:要更新的簇项号
dat:要将相应的簇项更新为dat
- 返回说明:无
- 注:在向文件写入了数据后,需要对FAT表进行更表,以表明新数据的簇链关系
删除文件的时候,也需要将该文件的簇项进行清除,销毁文件的簇链关系
**************************************************************************/
/*
void FAT32_Modify_FAT(UINT32 cluster,UINT32 dat)
{
FAT32_ReadSector(pArg->FirstFATSector+(cluster*4/pArg->BytesPerSector),FAT32_Buffer);
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+0]=dat&0x000000ff;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+1]=(dat&0x0000ff00)>>8;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+2]=(dat&0x00ff0000)>>16;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+3]=(dat&0xff000000)>>24;
FAT32_WriteSector(pArg->FirstFATSector+(cluster*4/pArg->BytesPerSector),FAT32_Buffer);
FAT32_ReadSector(pArg->FirstFATSector+pArg->FATsectors+(cluster*4/pArg->BytesPerSector),FAT32_Buffer);
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+0]=dat&0x000000ff;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+1]=(dat&0x0000ff00)>>8;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+2]=(dat&0x00ff0000)>>16;
FAT32_Buffer[((cluster*4)%pArg->BytesPerSector)+3]=(dat&0xff000000)>>24;
FAT32_WriteSector(pArg->FirstFATSector+pArg->FATsectors+(cluster*4/pArg->BytesPerSector),FAT32_Buffer);
}
*/
/**************************************************************************
- 功能描述:清空某个簇的所有扇区,填充0
- 隶属模块:znFAT文件系统模块
- 函数属性:内部
- 参数说明:cluster:要清空的簇的簇号
- 返回说明:无
**************************************************************************/
/*
void FAT32_Empty_Cluster(UINT32 Cluster)
{
UINT32 iSec;
UINT16 i;
for(i=0;i<pArg->BytesPerSector;i++)
{
FAT32_Buffer[i]=0;
}
for(iSec=SOC(Cluster);iSec<SOC(Cluster)+pArg->SectorsPerClust;iSec++)
{
FAT32_WriteSector(iSec,FAT32_Buffer);
}
}
*/
/**************************************************************************
- 功能描述:在存储设备中创建一个文件/目录项
- 隶属模块:FAT文件系统模块
- 函数属性:内部
- 参数说明:pfi:指向FileInfoStruct类型的结构体,用于装载刚创建的文件的信息
也就是说,如果创建的是目录,则此结构体不会被更新
cluster:在cluster这个簇中创建文件/目录项,用于实现在任意目录下
创建文件或目录,可以通过FAT32_Enter_Dir来获取某一个目录的开
始簇
name:文件/目录的名称
is_dir:指示要创建的是文件还是目录,文件与目录的创建方法是不同的
1表示创建目录 0表示创建文件
- 返回说明:成功返回1,失败返回-1
**************************************************************************/
/*
UINT8 FAT32_Create_Rec(struct FileInfoStruct *pfi,UINT32 cluster,INT8 *name,UINT8 is_dir,UINT8 *ptd)
{
UINT32 iSec,iRec,temp_sec,temp_clu,new_clu,i,old_clu;
UINT8 flag=0;
UINT16 temp_Rec;
struct direntry *pRec;
Fill_Rec_Inf(&temp_rec,name,is_dir,ptd);
do
{
old_clu=cluster;
temp_sec=SOC(cluster);
for(iSec=temp_sec;iSec<temp_sec+pArg->SectorsPerClust;iSec++)
{
FAT32_ReadSector(iSec,FAT32_Buffer);
for(iRec=0;iRec<pArg->BytesPerSector;iRec+=sizeof(struct direntry))
{
pRec=(struct direntry *)(FAT32_Buffer+iRec);
if((pRec->deName)[0]==0)
{
flag=1;
if(is_dir)
{
if(!(new_clu=FAT32_Find_Free_Clust(0))) return -1;
FAT32_Modify_FAT(new_clu,0x0fffffff);
(temp_rec.deHighClust)[0]=(new_clu&0x00ff0000)>>16;
(temp_rec.deHighClust)[1]=(new_clu&0xff000000)>>24;
(temp_rec.deLowCluster)[0]=(new_clu&0x000000ff);
(temp_rec.deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
}
FAT32_ReadSector(iSec,FAT32_Buffer);
for(i=0;i<sizeof(struct direntry);i++)
{
((UINT8 *)pRec)[i]=((UINT8 *)(&temp_rec))[i];
}
FAT32_WriteSector(iSec,FAT32_Buffer);
temp_sec=iSec;
temp_Rec=iRec;
iRec=pArg->BytesPerSector;
iSec=temp_sec+pArg->SectorsPerClust;
}
}
}
}while(!flag && (cluster=FAT32_GetNextCluster(cluster))!=0x0fffffff);
if(!flag)
{
if(!(temp_clu=FAT32_Find_Free_Clust(0))) return -1;
FAT32_Modify_FAT(temp_clu,0x0fffffff);
FAT32_Modify_FAT(old_clu,temp_clu);
temp_sec=SOC(temp_clu);
temp_Rec=0;
FAT32_ReadSector(temp_sec,FAT32_Buffer);
if(is_dir)
{
if(!(new_clu=FAT32_Find_Free_Clust(0))) return -1;
FAT32_Modify_FAT(new_clu,0x0fffffff);
FAT32_ReadSector(temp_sec,FAT32_Buffer);
(temp_rec.deHighClust)[0]=(new_clu&0x00ff0000)>>16;
(temp_rec.deHighClust)[1]=(new_clu&0xff000000)>>24;
(temp_rec.deLowCluster)[0]=(new_clu&0x000000ff);
(temp_rec.deLowCluster)[1]=(new_clu&0x0000ff00)>>8;
}
for(i=0;i<sizeof(struct direntry);i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -