/* 函数功能: 顺序读取整个文件 参数 : Target_File 目标文件 返回值 : u8* */ u8* ReadFile(FS_Object* Target_File) { if(Target_File->CurClus==FS_EOF) { return (void*)0; } if(Target_File->CurSec==FS.Sec_PerClus) { Target_File->CurSec=0; Target_File->CurClus=Read_NextClusNum(Target_File->CurClus); if(Target_File->CurClus==FS_EOF) { return (void*)0; } } ReadSec(Target_File->CurClus,Target_File->CurSec,FS_Buffer); Target_File->CurSec++; return (u8*)FS_Buffer; }
/********************************************************************************************************* ** 函数名称: FATGetNextClus ** 功能描述: 返回FAT表指定簇的下一个簇号 ** ** 输 入: Index:簇号 ** 输 出: 下一个簇号 ** ** 全局变量: 无 ** 调用模块: 无 ** ********************************************************************************************************/ Uint32 FATGetNextClus(Uint32 Index) { Uint16 temp, ByteIndex; Uint32 SecIndex; Uint8 *Buf; Uint32 Rt; if (Index >= (DiskInfo.ClusPerData)) { return BAD_CLUS; } /* 计算扇区号和字节索引 */ switch (DiskInfo.FATType) { case FAT12: SecIndex = Index * 3 / (2 * DiskInfo.BytsPerSec); ByteIndex = ((Index * 3) / 2) - (SecIndex * DiskInfo.BytsPerSec); SecIndex += DiskInfo.FATStartSec; break; case FAT16: SecIndex = Index * 2 / DiskInfo.BytsPerSec + DiskInfo.FATStartSec; ByteIndex = (Index * 2) & (DiskInfo.BytsPerSec - 1); break; case FAT32: SecIndex = Index * 4 / DiskInfo.BytsPerSec + DiskInfo.FATStartSec; ByteIndex = (Index * 4) & (DiskInfo.BytsPerSec - 1); break; default: return BAD_CLUS; } Buf = OpenSec(SecIndex); if (Buf == NULL) { return BAD_CLUS; } ReadSec(SecIndex, 0); /* 读取FAT表数据 */ switch (DiskInfo.FATType) { case FAT12: temp = Buf[ByteIndex]; ByteIndex++; if (ByteIndex >= DiskInfo.BytsPerSec) /* 下一个字节是否在下一个扇区 */ { Buf = OpenSec(SecIndex + 1); if (Buf == NULL) { return BAD_CLUS; } ReadSec(SecIndex + 1, 0); temp = temp | (Buf[0] << 8); } else { temp = temp | (Buf[ByteIndex] << 8); } if ((Index & 0x01) != 0) /* 判断哪12位有效 */ { temp = temp >> 4; } else {
/* 函数功能: 在文件夹中创建新文件(夹),并获取新创建文件(夹)参数 参数 : CurDir 当前文件夹 Target 目标文件(夹),新文件(夹)创建完成后,参数存于此结构体 Target_Name 目标文件(夹)名,新文件(夹)以此命名 Object FILE或DIR,用于区分将要创建的是文件还是文件夹 返回值 : NAME_ERROR 文件(夹)名错误,此文件(夹)已存在。 FILE_FAILED 文件(夹)创建失败,空间不足 FILE_SUCCESSED 文件(夹)创建成功 */ FS_Status CreateNewObject(FS_Object* CurDir,FS_Object *Target,u8 *Target_Name,u8 Object) { DIR_tag *DirTag; u32 LastClus; u32 CurClus; u32 NewObject_FstClus; u8 CurSec; u16 CurEntAddr; u32 TotalClus; if(Search_inDir(CurDir,Target,Target_Name,Object)==FILE_NOTEXIST) { TotalClus=(FS.FS_Size-FS.Data_Addr)/FS.Bytes_PerClus; CurClus=CurDir->FstClus; do { /***** Read and Scan FS_Object Data Aera by Sector ******/ for(CurSec=0;CurSec<FS.Sec_PerClus;CurSec++) { ReadSec(CurClus,CurSec,FS_Buffer); /***** Scan Every DirEntry , 32 Bytes per DirEntry! *****/ for(CurEntAddr=0;CurEntAddr<BYTES_PERSEC;CurEntAddr+=DIRENT_SIZE) { DirTag=(DIR_tag*)((u32)FS_Buffer+CurEntAddr); if((DirTag->FileName[0]==EMPTY)||(DirTag->FileName[0]==DELETED)) { NewObject_FstClus=Write_NextClusNum(FST_CLUS); ReadSec(CurClus,CurSec,FS_Buffer); Write_ShortNm(Target_Name,DirTag->FileName); DirTag->Attribute=Object; DirTag->FstClusHI=(u16)(NewObject_FstClus>>16); DirTag->FstClusLO=(u16)NewObject_FstClus; DirTag->FileLength=0x00; WriteSec(CurClus,CurSec,FS_Buffer); Target->Name=Target_Name; Target->Attrib=Object; Target->Size=0; Target->FstClus=NewObject_FstClus; Target->DirEntryAddr=Get_ClusAddr(CurClus)+CurSec*BYTES_PERSEC+CurEntAddr; Target->CurClus=Target->FstClus; Target->CurSec=0; return FILE_SUCCESSED; } } } LastClus=CurClus; CurClus=Read_NextClusNum(CurClus); if(CurClus==FS_EOF) { CurClus=Write_NextClusNum(LastClus); USART1_printf("NextClusNum:0x%x",CurClus); if(CurClus==FS_EOF) { return FILE_FAILED; } } }
/* 函数功能: 列出文件夹中的所有项目 参数 : CurDir 当前文件夹 返回值 : void */ void LsDir(FS_Object* CurDir) { DIR_tag *DirTag; LongDir_Ent *LongDirEnt; u32 CurClus; u16 CurEntAddr; u8 CurSec,LngNmCnt,DirEntCnt; u16 Name_Buffer[53]; //最多容纳4个目录项 共52个Unicode字符 u8 *Name; Name_Buffer[52]=0; CurClus=CurDir->FstClus; LngNmCnt=4; DirEntCnt=4; do { /***** Read and Scan FS_Object Data Aera by Sector ******/ for(CurSec=0;CurSec<FS.Sec_PerClus;CurSec++) { ReadSec(CurClus,CurSec,FS_Buffer); /***** Scan Every DirEntry , 32 Bytes per DirEntry! *****/ for(CurEntAddr=0;CurEntAddr<BYTES_PERSEC;CurEntAddr+=DIRENT_SIZE) { DirTag=(DIR_tag*)((u32)FS_Buffer+CurEntAddr); if(DirTag->FileName[0]==EMPTY) { return; } if(DirTag->FileName[0]!=DELETED) { if(DirTag->Attribute==LONG_NAME) { if(LngNmCnt!=0) { LngNmCnt--; LongDirEnt=(LongDir_Ent*)DirTag; Name=(u8 *)Name_Buffer+LngNmCnt*26; CopyRam(LongDirEnt->Name1,Name,10); CopyRam(LongDirEnt->Name2,Name+10,12); CopyRam(LongDirEnt->Name3,Name+22,4); } } else if(DirTag->Attribute&(DIR|FILE)) { if(DirTag->Attribute&DIR) { USART_SendStr(USART1,"Dir:"); } else { USART_SendStr(USART1,"File:"); } if(LngNmCnt!=4) { LngNmCnt=4; Convert_LngNm(Name); USART_SendStr(USART1,Name); USART1_printf("\r\n"); } else { Name=(u8 *)Name_Buffer; CopyRam(DirTag->FileName,Name,11); Convert_ShortNm(Name); USART_SendStr(USART1,Name); USART1_printf("\r\n"); } } } if(LngNmCnt!=4) { DirEntCnt--; } if(LngNmCnt!=DirEntCnt) { LngNmCnt=4; DirEntCnt=4; } } } CurClus=Read_NextClusNum(CurClus); } while(CurClus!=0x0fffffff); return; }
/* 函数功能: 根据文件(夹)名在文件夹中寻找文件(夹),如果找到则获取文件(夹)参数 参数 : CurDir 结构体指针,当前文件夹 Target 结构体指针,目标文件(夹) Target_Name 目标文件(夹)名 Object FILE或DIR,用于区分目标是文件还是文件夹 返回值 : FILE_EXIST或FILE_NOTEXIST */ FS_Status Search_inDir(FS_Object *CurDir, FS_Object *Target, u8 *Target_Name, u8 Object) { DIR_tag *DirTag; LongDir_Ent *LongDirEnt; u32 CurClus; u16 CurEntAddr; u8 CurSec,LngNmCnt,DirEntCnt; u16 Name_Buffer[53]; //最多容纳4个目录项 共52个Unicode字符 u8 *Name; Name_Buffer[52]=0; CurClus=CurDir->FstClus; LngNmCnt=4; DirEntCnt=4; do { /***** Read and Scan FS_Object Data Aera by Sector ******/ for(CurSec=0;CurSec<FS.Sec_PerClus;CurSec++) { ReadSec(CurClus,CurSec,FS_Buffer); /***** Scan Every DirEntry , 32 Bytes per DirEntry! *****/ for(CurEntAddr=0;CurEntAddr<BYTES_PERSEC;CurEntAddr+=DIRENT_SIZE) { DirTag=(DIR_tag*)((u32)FS_Buffer+CurEntAddr); if(DirTag->FileName[0]==EMPTY) { return FILE_NOTEXIST; } if(DirTag->FileName[0]!=DELETED) { if(DirTag->Attribute==LONG_NAME) { if(LngNmCnt!=0) { LngNmCnt--; LongDirEnt=(LongDir_Ent*)DirTag; Name=(u8 *)Name_Buffer+LngNmCnt*26; CopyRam(LongDirEnt->Name1,Name,10); CopyRam(LongDirEnt->Name2,Name+10,12); CopyRam(LongDirEnt->Name3,Name+22,4); } } else if(DirTag->Attribute&Object) { if(LngNmCnt!=4) { LngNmCnt=4; Convert_LngNm(Name); } else { Name=(u8 *)Name_Buffer; CopyRam(DirTag->FileName,Name,11); Convert_ShortNm(Name); } if(CompareName(Name,Target_Name)==SUCCESSED) { Target->Name =Target_Name; Target->Attrib =DirTag->Attribute; Target->Size =DirTag->FileLength; Target->FstClus=DirTag->FstClusHI; Target->FstClus<<=16; Target->FstClus+=DirTag->FstClusLO; Target->DirEntryAddr=Get_ClusAddr(CurClus) +CurSec*BYTES_PERSEC +CurEntAddr; Target->CurClus=Target->FstClus; Target->CurSec=0; return FILE_EXIST; } } if(LngNmCnt!=4) { DirEntCnt--; } if(LngNmCnt!=DirEntCnt) { LngNmCnt=4; DirEntCnt=4; } } } } CurClus=Read_NextClusNum(CurClus); } while(CurClus!=0x0fffffff); return FILE_NOTEXIST; }