📄 fat32.c
字号:
#include <string.h>
#include "..\inc\usb\bitops.h"
#include "..\inc\option.h"
#include "..\inc\def.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\ata.h"
#include "..\inc\fat32def.h"
//FAT 32 Byte Directory Entry Structure//
struct dir_stru
{
U8 DIR_Name[11]; //Short name. //
U8 DIR_Attr; //File attributes.The upper two bits of the attribute byte are//
//reserved and should always be set to 0 when a file is //
//created and never modified or looked at after that. //
U8 DIR_NTRes; //Reserved for use by Windows NT. Set value to 0 when a file is//
//created and never modify or look at it after that. //
U8 DIR_CrtTimeTenth;
U16 DIR_CrtTime;
U16 DIR_CrtDate;
U16 DIR_LstAccDate;
U16 DIR_FstClusHI; //High word of this entry's first cluster number always 0 for a//
//FAT12 or FAT16 volume. //
U16 DIR_WrtTime;
U16 DIR_WrtDate;
U16 DIR_FstClusLO;
U32 DIR_FileSize;
};
struct dir_info
{
U8 Name[11];
U8 Attr;
U32 Location;
U32 Size;
};
struct dir_info Current_Dir_Info[MAX_DIR_FILE_NUM];
U16 Current_Dir_Total_File_Num;//当前目录表中有效的文件数
U32 BPB_Location;
U32 FAT1_Locate; // in LBA mode //
U8 FAT_Num;
U32 FAT_Sectors;
U32 FAT2_Locate; // in LBA mode //
U32 Data_Offset; // in LBA mode(the Start LBA Sector of Cluster 2) //
U32 Data_Sectors;
U8 Cluster_Size; // 以Sector为单位
U32 Total_Clusters;
U32 Root_Locate; // 以Cluster为单位 //
void Read_File(U32 file_location);
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
U32 Get_Next_Cluster(U32 Current_Cluster)
{
static U32 old_fat_location;
static U32 FAT_Sector_Buf[Sector_Size/4];
U32 new_fat_location;
new_fat_location=(Current_Cluster/(Sector_Size/4))+FAT1_Locate;
if(new_fat_location!=old_fat_location) //需要重读一个新的FAT扇区
{
Read_Sectors(Current_DRV,new_fat_location,(U8 *)FAT_Sector_Buf);
old_fat_location=new_fat_location;
}
return(FAT_Sector_Buf[Current_Cluster%(Sector_Size/4)]);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
U32 Cluster2LBA(U32 cluster)
{
return((cluster-First_Cluster_Num)*Cluster_Size+Data_Offset);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void Read_Cluster(U32 cluster,U8 * dest_buf)
{
U8 sector_num;
U32 lba_num;
lba_num=Cluster2LBA(cluster);
for(sector_num=0;sector_num<Cluster_Size;sector_num++)
{
Read_Sectors(Current_DRV,(lba_num+sector_num),(U8 *)(dest_buf+Sector_Size*sector_num));
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void Read_Dir(U32 dir_location)
{
U16 i,name_pointer,dir_pointer=0;
struct dir_stru * DIR_Buf;
Current_Dir_Total_File_Num=0; //reset current dir total file number
while(dir_location<FAT_Last_Cluster)
{
DIR_Buf=(struct dir_stru *)malloc(Cluster_Size*Sector_Size);//Cluster_Size*Sector_Size);
Read_Cluster(dir_location,(U8 *)DIR_Buf);
for(i=0;i<((Cluster_Size*Sector_Size)/32);i++)
{
if((DIR_Buf[i].DIR_Name[0]!=SLOT_EMPTY)\
&&(DIR_Buf[i].DIR_Name[0]!=SLOT_DELETED)\
&&((DIR_Buf[i].DIR_Attr&0x0f)==0x00)\
&&(dir_pointer<MAX_DIR_FILE_NUM))
{
for(name_pointer=0;name_pointer<11;name_pointer++)
Current_Dir_Info[dir_pointer].Name[name_pointer]=DIR_Buf[i].DIR_Name[name_pointer];
Current_Dir_Info[dir_pointer].Attr=DIR_Buf[i].DIR_Attr;
Current_Dir_Info[dir_pointer].Location/*U32*/=DIR_Buf[i].DIR_FstClusHI/*U16*/*65536+DIR_Buf[i].DIR_FstClusLO/*U16*/;
Current_Dir_Info[dir_pointer].Size=DIR_Buf[i].DIR_FileSize;
dir_pointer++;
Current_Dir_Total_File_Num++;
}
}
free(DIR_Buf);
dir_location=Get_Next_Cluster(dir_location);
}
for(dir_pointer=0;dir_pointer<Current_Dir_Total_File_Num;dir_pointer++)
{
if(Current_Dir_Info[dir_pointer].Attr==ATTR_FILE)
Uart_Printf("\nFileNum %3d-:",dir_pointer);
else
Uart_Printf("\nFileNum %3d+:",dir_pointer);
for(name_pointer=0;name_pointer<11;name_pointer++)
{
Uart_Printf("%c",Current_Dir_Info[dir_pointer].Name[name_pointer]);
}
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void Read_BPB(U32 bpb_location)
{
U8 BPB_Buf[Sector_Size];
Read_Sectors(Current_DRV,bpb_location,BPB_Buf);
FAT1_Locate =BPB_Buf[Offset_U16_BPB_RsvdSecCnt]\
+BPB_Buf[Offset_U16_BPB_RsvdSecCnt+1]*256\
+bpb_location;
FAT_Sectors =BPB_Buf[Offset_U32_BPB_FATSz32]\
+BPB_Buf[Offset_U32_BPB_FATSz32+1]*256\
+BPB_Buf[Offset_U32_BPB_FATSz32+2]*256*256\
+BPB_Buf[Offset_U32_BPB_FATSz32+3]*256*256*256;
FAT_Num=BPB_Buf[Offset_U8_BPB_NumFATs];
if(FAT_Num==0x02)
FAT2_Locate=FAT1_Locate+FAT_Sectors;
else
FAT2_Locate=FAT1_Locate;
Root_Locate =BPB_Buf[Offset_U32_BPB_RootClus]\
+BPB_Buf[Offset_U32_BPB_RootClus+1]*256\
+BPB_Buf[Offset_U32_BPB_RootClus+2]*256*256\
+BPB_Buf[Offset_U32_BPB_RootClus+3]*256*256*256;
Data_Offset =FAT1_Locate+FAT_Num*FAT_Sectors\
+(((BPB_Buf[Offset_U16_BPB_RootEntCnt]+BPB_Buf[Offset_U16_BPB_RootEntCnt+1]*256)*32)/HDD_Sector_Size);
Data_Sectors =BPB_Buf[Offset_U32_BPB_TotSec32]\
+BPB_Buf[Offset_U32_BPB_TotSec32+1]*256\
+BPB_Buf[Offset_U32_BPB_TotSec32+2]*256*256\
+BPB_Buf[Offset_U32_BPB_TotSec32+3]*256*256*256;
Cluster_Size =BPB_Buf[Offset_U8_BPB_SecPerClus];
Total_Clusters=Data_Sectors/Cluster_Size;
Read_Dir(Root_Locate);
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void Read_MBR(void)
{
U8 MBR_Buf[Sector_Size];
Read_Sectors(Current_DRV,MBR_Location,MBR_Buf);
// Get the BPB Location in LBA mode //
BPB_Location =MBR_Buf[BPB_Offset]\
+MBR_Buf[BPB_Offset+1]*256\
+MBR_Buf[BPB_Offset+2]*256*256\
+MBR_Buf[BPB_Offset+3]*256*256*256;
Read_BPB(BPB_Location); // Read BPB information //
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void FAT32_Tools(void)
{
U8 aa;
U16 name_pointer,dir_pointer=0;
Uart_Printf("\n* - :Prev File *");
Uart_Printf("\n* + :Next File *");
Uart_Printf("\n* 0 :Select File *");
Uart_Printf("\n* Q(q):Quit *");
while(1)
{
aa= Uart_Getch();
if((aa=='q')||(aa=='Q'))
break;
switch(aa)
{
case '+':
dir_pointer++;
if(dir_pointer==Current_Dir_Total_File_Num)
dir_pointer=0;
if((Current_Dir_Info[dir_pointer].Attr&0xf0)==ATTR_FILE)
Uart_Printf("\nCurrentNum %3d-:",dir_pointer);
else
Uart_Printf("\nCurrentNum %3d+:",dir_pointer);
for(name_pointer=0;name_pointer<11;name_pointer++)
{
Uart_Printf("%c",Current_Dir_Info[dir_pointer].Name[name_pointer]);
}
break;
case '-':
if(dir_pointer==0)
dir_pointer=Current_Dir_Total_File_Num-1;
else
dir_pointer--;
if((Current_Dir_Info[dir_pointer].Attr&0xf0)==ATTR_FILE)
Uart_Printf("\nCurrentNum %3d-:",dir_pointer);
else
Uart_Printf("\nCurrentNum %3d+:",dir_pointer);
for(name_pointer=0;name_pointer<11;name_pointer++)
{
Uart_Printf("%c",Current_Dir_Info[dir_pointer].Name[name_pointer]);
}
break;
case '0':
if(Current_Dir_Info[dir_pointer].Attr==ATTR_DIRECTORY)
{
if(Current_Dir_Info[dir_pointer].Location==0)//Zero mean ROOT
Current_Dir_Info[dir_pointer].Location=Root_Locate;
Read_Dir(Current_Dir_Info[dir_pointer].Location);
dir_pointer=0;
}
else
Read_File(Current_Dir_Info[dir_pointer].Location);
break;
}
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void Read_File(U32 file_location)
{
U8 * File_Buf;
Uart_Printf("\n Start to read!");
while(file_location<FAT_Last_Cluster)
{
File_Buf=(U8 *)malloc(Cluster_Size*Sector_Size);//Cluster_Size*Sector_Size);
Read_Cluster(file_location,File_Buf);
free(File_Buf);
file_location=Get_Next_Cluster(file_location);
}
Uart_Printf("\n read finished!");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -