?? znfat.c
字號:
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=znFAT_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
pfi->FileCurSector=j;
znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
temp=len-counter;
for(i=0;i<temp;i++)
{
if(counter>=len)
{
return len;
}
pbuf[counter]=znFAT_Buffer[i];
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
else
{
len=0;
}
return len;
}
#endif
/**************************************************************************
- 功能描述:從文件某一位置讀取一定長度的數據,由pfun所指向的函數來處理
- 隸屬模塊:znFAT文件系統模塊
- 函數屬性:外部,使用戶使用
- 參數說明:pfi:FileInfoStruct類型的結構體指針,用于裝載文件參數信息,文件
讀取的過程中,此結構體中的相關參數會更新,比如文件的當前偏移量、
文件的當前扇區,文件的當前簇等等
offset:要定位的偏移量,要小于文件的大小
len:要讀取的數據的長度,如果len+offset大于文件的大小,則實際讀
取的數據量是從offset開始到文件結束
pfun:對讀取的數據的處理函數,pfun指向處理函數,這樣可以靈活的
配置數據如何去處理,比如是放在緩沖區中,還是把數據通過串口發送
出去,只需要pfun去指向相應的處理函數可以了
- 返回說明:讀取到的實際的數據長度,如果讀取失敗,比如指定的偏移量大于了文件
大小,則返回0
- 注:在讀取一個文件的數據前,必須先將該文件用znFAT_Open_File打開
**************************************************************************/
#ifdef ZNFAT_READ_FILEX
UINT32 znFAT_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;
znFAT_Seek_File(pfi,offset);
znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
for(i=pfi->FileCurPos;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(znFAT_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++)
{
znFAT_ReadSector(j,znFAT_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(znFAT_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurOffset++;
}
}
}
temp=(len-counter)/(pArg->BytesPerSector*pArg->SectorsPerClust);
for(k=0;k<temp;k++)
{
pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
for(j=(SOC(pfi->FileCurCluster));j<(SOC(pfi->FileCurCluster))+pArg->SectorsPerClust;j++)
{
znFAT_ReadSector(j,znFAT_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(znFAT_Buffer[i]);
counter++;
pfi->FileCurOffset++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
}
}
}
pfi->FileCurCluster=znFAT_GetNextCluster(pfi->FileCurCluster);
temp=(SOC(pfi->FileCurCluster))+((len-counter)/pArg->BytesPerSector);
pfi->FileCurSector=(SOC(pfi->FileCurCluster));
for(j=(SOC(pfi->FileCurCluster));j<temp;j++)
{
znFAT_ReadSector(j,znFAT_Buffer);
pfi->FileCurSector=j;
for(i=0;i<pArg->BytesPerSector;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(znFAT_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
pfi->FileCurSector=j;
znFAT_ReadSector(pfi->FileCurSector,znFAT_Buffer);
temp=len-counter;
for(i=0;i<temp;i++)
{
if(counter>=len)
{
return len;
}
(*pfun)(znFAT_Buffer[i]);
counter++;
pfi->FileCurPos++;
pfi->FileCurPos%=pArg->BytesPerSector;
pfi->FileCurOffset++;
}
}
else
{
len=0;
}
return len;
}
#endif
/**************************************************************************
- 功能描述:尋找可用的空閑簇
- 隸屬模塊:znFAT文件系統模塊
- 函數屬性:內部
- 參數說明:無
- 返回說明:如果找到了空閑簇,返回空閑簇的簇號,否則返回0
- 注:尋找空閑簇是創建目錄/文件以及向文件寫入數據的基礎,它如果能很快的尋
找到空閑簇,那么創建目錄/文件以及向文件寫入數據這些操作也會比較快。
所以我們絕不會從最開始的簇依次去尋找,而是使用了二分搜索的算法,以達
到較好的效果。如果空閑簇沒有找到,很有可能就說明存儲設備已經沒有空間
了
**************************************************************************/
#ifdef ZNFAT_FIND_FREE_CLUST
UINT32 znFAT_Find_Free_Clust(UINT8 flag)
{
UINT32 iClu,iSec;
struct znFAT_FAT *pFAT;
for(iSec=pArg->FirstFATSector+temp_last_cluster/128;iSec<pArg->FirstFATSector+pArg->FATsectors;iSec++)
{
znFAT_ReadSector(iSec,znFAT_Buffer);
pFAT=(struct znFAT_FAT *)znFAT_Buffer;
for(iClu=0;iClu<pArg->BytesPerSector/4;iClu++)
{
if(LE2BE((UINT8 *)(&((pFAT->Items))[iClu]),4)==0)
{
if(!flag)
{
znFAT_Update_FSInfo_Free_Clu(0);
temp_last_cluster=128*(iSec-pArg->FirstFATSector)+iClu;
znFAT_Empty_Cluster(temp_last_cluster);
return temp_last_cluster;
}
else
{
znFAT_Update_FSInfo_Last_Clu(128*(iSec-pArg->FirstFATSector)+iClu);
return 128*(iSec-pArg->FirstFATSector)+iClu;
}
}
}
}
return 0;
}
#endif
/**************************************************************************
- 功能描述:填充文件/目錄項
- 隸屬模塊:znFAT文件系統模塊
- 函數屬性:內部
- 參數說明:prec:指向一個direntry類型的結構體,它的結構就是znFAT中文件/
目錄項的結構
name:文件或目錄的名稱
is_dir:指示這個文件/目錄項是文件還是目錄,分別用來實現文件、
目錄的創建 1表示創建目錄 0表示創建文件
- 返回說明:無
- 注:這里創建文件或目錄的方法是,先將文件或目錄的信息填充到一個結構體中,
然后再將這個結構體的數據寫入到存儲設備的相應的扇區的相應位置上去,這
樣就完成了文件或目錄的創建。
在填充文件或目錄的信息時,文件或目錄的首簇并沒有填進去,而是全0
**************************************************************************/
#ifdef FILL_REC_INF
void Fill_Rec_Inf(struct direntry *prec,INT8 *name,UINT8 is_dir,UINT8 *ptd)
{
UINT8 i=0,len=0,h=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]!=0) {if(name[len]=='.') h=1;len++;}
if(!h) {name[len]='.';name[len+1]=0;}
len=0;
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;
}
}
#endif
/**************************************************************************
- 功能描述:更新FAT表
- 隸屬模塊:znFAT文件系統模塊
- 函數屬性:內部
- 參數說明:cluster:要更新的簇項號
dat:要將相應的簇項更新為dat
- 返回說明:無
- 注:在向文件寫入了數據后,需要對FAT表進行更表,以表明新數據的簇鏈關系
刪除文件的時候,也需要將該文件的簇項進行清除,銷毀文件的簇鏈關系
**************************************************************************/
#ifdef ZNFAT_MODIFY_FAT
void znFAT_Modify_FAT(UINT32 cluster,UINT32 dat)
{
znFAT_ReadSector(pArg->FirstFATSector+(cluster*4/pArg->BytesPerSector),znFAT_Buffer);
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+0]=dat&0x000000ff;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+1]=(dat&0x0000ff00)>>8;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+2]=(dat&0x00ff0000)>>16;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+3]=(dat&0xff000000)>>24;
znFAT_WriteSector(pArg->FirstFATSector+(cluster*4/pArg->BytesPerSector),znFAT_Buffer);
znFAT_ReadSector(pArg->FirstFATSector+pArg->FATsectors+(cluster*4/pArg->BytesPerSector),znFAT_Buffer);
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+0]=dat&0x000000ff;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+1]=(dat&0x0000ff00)>>8;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+2]=(dat&0x00ff0000)>>16;
znFAT_Buffer[((cluster*4)%pArg->BytesPerSector)+3]=(dat&0xff000000)>>24;
znFAT_WriteSector(pArg->FirstFATSector+pArg->FATsectors+(cluster*4/pArg->BytesPerSector),znFAT_Buffer);
}
#endif
/**************************************************************************
- 功能描述:在存儲設備中創建一個文件/目錄項
- 隸屬模塊:znFAT文件系統模塊
- 函數屬性:內部
- 參數說明:pfi:指向FileInfoStruct類型的結構體,用于裝載剛創建的文件的信息
也就是說,如果創建的是目錄,則此結構體不會被更新
cluster:在cluster這個簇中創建文件/目錄項,用于實現在任意目錄下
創建文件或目錄,可以通過znFAT_Enter_Dir來獲取某一個目錄的開
始簇
name:文件/目錄的名稱
is_dir:指示要創建的是文件還是目錄,文件與目錄的創建方法是不同的
1表示創建目錄 0表示創建文件
- 返回說明:成功返回1,失敗返回-1
**************************************************************************/
#ifdef ZNFAT_CREATE_REC
UINT8 znFAT_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++)
{
znFAT_ReadSector(iSec,znFAT_Buffer);
for(iRec=0;iRec<pArg->BytesPerSector;iRec+=sizeof(struct direntry))
{
pRec=(struct direntry *)(znFAT_Buffer+iRec);
if((pRec->deName)[0]==0)
{
flag=1;
if(is_dir)
{
if(!(new_clu=znFAT_Find_Free_Clust(0))) return -1;
znFAT_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;
}
znFAT_ReadSector(iSec,znFAT_Buffer);
for(i=0;i<sizeof(struct direntry);i++)
{
((UINT8 *)pRec)[i]=((UINT8 *)(&temp_rec))[i];
}
znFAT_WriteSector(iSec,znFAT_Buffer);
temp_sec=iSec;
temp_Rec=iRec;
iRec=pArg->BytesPerSector;
iSec=temp_sec+pArg->SectorsPerClust;
}
}
}
}while(!flag && (cluster=znFAT_GetNextCluster(cluster))!=0x0fffffff);
if(!flag)
{
if(!(temp_clu=znFAT_Find_Free_Clust(0))) return -1;
znFAT_Modify_FAT(temp_clu,0x0fffffff);
znFAT_Modify_FAT(old_clu,temp_clu);
temp_sec=SOC(temp_clu);
temp_Rec=0;
znFAT_ReadSector(temp_sec,znFAT_Buffer);
if(is_dir)
{
if(!(new_clu=znFAT_Find_Free_Clust(0))) return -1;
znFAT_Modify_FAT(new_clu,0x0fffffff);
znFAT_ReadSector(temp_sec,znFAT_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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -