本帖最后由 petp 于 2014-11-16 21:22 编辑
petp 发表于 2014-11-16 18:52
***************************
复杂的open file 函数—— 第一个拦路虎
**************************
把 Open file 再简单些
********************************
上面的 open file 函数之所以显得很复杂,是因为 要 查到最后一级目录,相对于曲折了很多。
如果直接打开根目录中的文件,函数就会简化很多。
//自创函数,非znFAT中函数,只是为了展示open file 函数,而简化,类似伪代码
UINT8 znFAT_Open_File_of_Root(structFileInfo *pfi) { UINT8 flag=0; UINT32 sec_temp=0,Cur_Cluster=2,fn_pos=1; UINT32 iSec=0,iFDI=0; INT8 *filename; struct FDIesInSEC *pitems; //指向文件目录项扇区数据的指针 struct FDI *pitem; //指向文件目录项数据的指针 //================================================ do { sec_temp=SOC(Cur_Cluster); //当前簇首扇区 for(iSec=0;iSec<(pInit_Args->SectorsPerClust);iSec++) { znFAT_Device_Read_Sector(sec_temp+(UINT32)iSec,znFAT_Buffer); pitems=(struct FDIesInSEC *)znFAT_Buffer; for(iFDI=0;iFDI<NFDI_PER_SEC;iFDI++) //访问扇区中各文件目录项 { pitem=&(pitems->FDIes[iFDI]); //指向一个文件目录项数据 To_File_Name((INT8*)(pitem->Name),temp_filename); //将FDI中的文件名字段转为8.3文件名 if(!SFN_Match(filename,temp_filename)) //短文件名通配 { Analyse_FDI(pfi,pitem); //解析匹配的文件目录项 pfi->FDI_Sec=sec_temp+iSec; //文件目录项所在的扇区 pfi->nFDI=(UINT8)iFDI; //文件目录项在扇区中的索引 return ERR_SUCC; flag=1; }// if(!SFN_Match(filename,temp_filename)) }// for }//for Cur_Cluster=Get_Next_Cluster(Cur_Cluster); //获取下一簇 }while(!IS_END_CLU(Cur_Cluster)); //如果不是最后一个簇,则继续循环 return ERR_NO_FILE;
}
这个函数的核心是 Analyse_FDI(pfi,pitem); //解析匹配的文件目录项
这样才能将文件相关参数填入文件信息集合,如目录创建时间等
**************************************
看起来非常简单的 文件目录项解析函数
/************************************************************************ 功能:解析一个文件目录项,将解析得到的参数装入到文件信息集合中 形参:pfi:指向文件信息集合的指针pFDI:指向文件目录项的指针 返回:0 详解:此函数被打开文件的函数调用,对符合匹配条件的文件目录项进行解析,并将参数装入到文件信 息集合中,以便对文件进行进一步的操作时使用。 *************************************************************************/ UINT8 Analyse_FDI(struct FileInfo*pfi,struct FDI *pFDI) { UINT32 temp=0,i=0; just_file=pfi; pfi->File_Attr=pFDI->Attributes; //文件属性 pfi->File_StartClust=Bytes2Value(pFDI->LowClust,2)+Bytes2Value(pFDI->HighClust,2)*65536; pfi->File_Size=Bytes2Value(pFDI->FileSize,4); //解析文件创建时间与日期 temp=Bytes2Value(pFDI->CTime,2); pfi->File_CTime.sec=(UINT8)((temp&TIME_SEC_MARK)*2);temp>>=TIME_SEC_NBITS; //创建时间的2秒位 pfi->File_CTime.min=(UINT8)(temp&TIME_MIN_MARK); temp>>=TIME_MIN_NBITS; //创建时间的分位 pfi->File_CTime.hour=(UINT8)(temp&TIME_HOUR_MARK);//创建时间的时位 pfi->File_CTime.sec+=(UINT8)((UINT16)(pFDI->CTime10ms)/100);//在秒上加上10毫秒位 temp=Bytes2Value(pFDI->CDate,2); pfi->File_CDate.day=(UINT8)(temp&DATE_DAY_MARK); temp>>=DATE_DAY_NBITS; //创建日期的日位 pfi->File_CDate.month=(UINT8)(temp&DATE_MONTH_MARK);temp>>=DATE_MONTH_NBITS; //创建日期的月位 pfi->File_CDate.year=(UINT16)((temp&DATE_YEAR_MARK)+DATE_YEAR_BASE);//创建日期的年位(加上年份基数) pfi->File_CurClust=pfi->File_StartClust; pfi->File_CurSec=(pfi->File_CurClust)?SOC(pfi->File_CurClust):0; pfi->File_CurPos=0; pfi->File_CurOffset=0; pfi->File_IsEOF=(UINT8)((pfi->File_StartClust)?BOOL_FALSE:BOOL_TRUE); return 0; }
*************************************
再回到主函数,
。。。
UART_Send_Num(fileinfo.File_CDate.year); UART_Send_Str("年");
UART_Send_Num(fileinfo.File_CDate.month);UART_Send_Str("月");
。。。。
主函数中的结构体中数据就来自解析函数的贡献。
|