⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat32.c

📁 ertfs文件系统里面既有完整ucos程序
💻 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 + -