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

📄 fat.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************** * * fat.c * * CVS ID:   $Id: * Author:   Michal Chlapik [ MCH ] - STM * Date:     $Date: 2007/08/15 09:25:20 $ * Revision: $Revision: 1.26 $ * * Description: * *   <...> * *************************************************** * * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * **************************************************** * * STM CVS Log: * * $Log: FAT.c,v $ * Revision 1.26  2007/08/15 09:25:20  trubac * error handling improved in FAT entry parsing * * Revision 1.25  2007/07/24 15:50:10  trubac * Fix for slow FAT mounting, FatEntryCheck added * * Revision 1.24  2007/06/04 16:58:44  longauer * USBtask rearrangement in order to support more logical units; new file usb_pri.h added with USBtask private declarations; USB compilation switches added; constants renaming; * * Revision 1.23  2007/05/09 07:31:09  chlapik * handling of situation if some cluster is marked as bad in FAT table * * Revision 1.22  2007/01/30 12:35:21  chlapik * max device block size as #define set to 2048B * * Revision 1.21  2007/01/29 14:32:00  chlapik * support for USB devices with any block size (not only 512B) * * Revision 1.20  2006/10/23 13:47:10  belardi * Added variable initialization to remove compiler warning * * Revision 1.19  2006/09/18 09:55:22  belardi * Corrected CVS keyword usage * * Revision 1.18  2006/09/18 09:24:02  belardi * Added Log CVS keyword into file header * * ***************************************************/#include "configuration.h"#if (HAVE_FAT)#include "apdevsys.h"#include "debug.h"#include "utf8.h"#include <ctype.h>#include "xfile.h"#include "filesys.h"#include "FAT.h"#include "usb.h"uint32 Get_RootDirSectors(BPB_boot_common_t *BPB_boot_common){       if(BPB_boot_common->RootEntCnt)         return ( (((uint32)(BPB_boot_common->RootEntCnt)<<5)+BPB_boot_common->BytesPerSec-1)>>get_val_log2(BPB_boot_common->BytesPerSec) );       else         return 0;}uint32 Get_FirstDataSector(BPB_boot_common_t *BPB_boot_common){     uint32 FATSz;     if((BPB_boot_common->FATSz16) != 0)       FATSz = BPB_boot_common->FATSz16;     else       FATSz = BPB_boot_common->FATSz32Estim;     return BPB_boot_common->RsvdSecCnt+BPB_boot_common->NumFATs*(uint32)FATSz+Get_RootDirSectors(BPB_boot_common);}uint32 Get_FirstSectorofCluster(BPB_boot_common_t *BPB_boot_common, uint32 FirstDataSector, uint32 Cluster){     return (Cluster-2)*BPB_boot_common->SecPerClust+FirstDataSector;}uint32 Get_FAT12_16_FirstRootDirSecNum(BPB_boot_common_t *BPB_boot_common){         //FAT 12 or 16         return BPB_boot_common->RsvdSecCnt+BPB_boot_common->NumFATs*(uint32)(BPB_boot_common->FATSz16);}uint8 ParseShortEntryName(uint8 *ShortEntry, uint16 *Name, uint8 *Ext){      uint8 Character;      uint8 i,j=0,k;      //scan first 8 characters      for(i=0;i<8;i++)      {        if((Character=ShortEntry[i])==0x20)          break;        Name[i]=(uint16)Character;      }      //scan for ext      if(ShortEntry[8]!=0x20)      { //there is ext        Name[i]=0x2E;        i++;        for(j=0;j<3;j++)        {          if((Character=ShortEntry[8+j])==0x20)            break;          Name[i+j]=(uint16)Character;          Ext[j]=Character;        }        //fill the rest of Ext with 0x20        for(k=0;k<3-j;k++)          Ext[k+j]=0x20;      }      else      { //no ext, fill Ext array with 0x20        for(k=0;k<3;k++)          Ext[k]=0x20;      }      return (i+j);}uint8 ParseLongEntryName(uint8 *LongEntry, uint16 *Name){     uint16 Character;     uint8 NumOfCharacters=0;     uint8 i;     //scan 5 characters, 1-5     for(i=0;i<5;i++)     {#ifdef DSP       if((Character=*((PACKED uint16*)&LongEntry[1+2*i])) != 0x0)#else       if((Character=*((uint16*)&LongEntry[1+2*i])) != 0x0)#endif       {         Name[i] = Character;         NumOfCharacters++;       }       else         return NumOfCharacters;     }     //scan 6 characters, 6-11     for(i=0;i<6;i++)     {#ifdef DSP       if((Character=*((PACKED uint16*)&LongEntry[14+2*i])) != 0x0)#else       if((Character=*((uint16*)&LongEntry[14+2*i])) != 0x0)#endif       {         Name[i+5] = Character;         NumOfCharacters++;       }       else         return NumOfCharacters;     }     //scan 2 characters, 12-13     for(i=0;i<2;i++)     {#ifdef DSP       if((Character=*((PACKED uint16*)&LongEntry[28+2*i])) != 0x0)#else       if((Character=*((uint16*)&LongEntry[28+2*i])) != 0x0)#endif       {         Name[i+11] = Character;         NumOfCharacters++;       }       else         return NumOfCharacters;     }     return NumOfCharacters;}uint8 ChkSum(uint8 *Name){     uint8 Sum;     int FcbNameLen;     Sum = 0;     for(FcbNameLen=11;FcbNameLen!=0;FcbNameLen--)       Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *Name++;     return Sum;}boolean CmpExts(uint8 *ExtTblItem, uint8 *Ext){     uint32 j;     for(j=0;j<3;j++)     {       if(ExtTblItem[j]!=Ext[j])         return false;     }     return true;}boolean FindExtInTbl(uint8 ExtTbl[][3], uint8 *Ext, uint32 ExtTblLen){     uint32 i;     for(i=0;i<ExtTblLen;i++)     { //tbl item       if(CmpExts(ExtTbl[i],Ext))         return true;     }     return false;}boolean CheckIfEOF(BPB_boot_common_t *BPB_boot_common, uint32 FATContent){     switch(BPB_boot_common->FATType)     {       case 1: if(FATContent >= 0x0FF8)                 return true;               break;       case 2: if(FATContent >= 0xFFF8)                 return true;               break;       case 0: if(FATContent >= 0x0FFFFFF8)                 return true;               break;     }     return false;}boolean CheckIfBadCluster(BPB_boot_common_t *BPB_boot_common, uint32 FATContent){     switch(BPB_boot_common->FATType)     {       case 1: if(FATContent == 0x0FF7)                 return true;               break;       case 2: if(FATContent == 0xFFF7)                 return true;               break;       case 0: if(FATContent == 0x0FFFFFF7)                 return true;               break;     }     return false;}SectorAndOffset_t Get_SectorAndOffset(BPB_boot_common_t *BPB_boot_common, uint32 Cluster){     uint32 FATOffset;      SectorAndOffset_t SectorAndOffset;     switch(BPB_boot_common->FATType)     {       case 0: FATOffset = (Cluster<<2);                //FAT 32               break;       case 1: FATOffset = Cluster + (Cluster>>1);      //FAT 12               break;       default: // [RB] initialize to some sane value to avoid compiler warning       case 2: FATOffset = (Cluster<<1);                //FAT 16               break;     }     SectorAndOffset.Sector = BPB_boot_common->RsvdSecCnt + (FATOffset>>get_val_log2(BPB_boot_common->BytesPerSec));     //SectorAndOffset.Offset = FATOffset - temp*BPB_boot_common->BytesPerSec;     SectorAndOffset.Offset = (FATOffset & (BPB_boot_common->BytesPerSec-1));     return SectorAndOffset;}GRESULT Get_FATEntry(FS_DESCRIPTOR *fsd, uint32 *FATClusEntryVal, uint8 *SecBuff){       //uint8 SecBuff[4096];              //alloc memory for sector of size BytesPerSec       SectorAndOffset_t FATEntry;       uint32 Cluster = *FATClusEntryVal;       GRESULT ReturnCode;       uint32 i,FATSz;              FATEntry = Get_SectorAndOffset(&(fsd->PD.FAT_pd.BPB_boot_common),Cluster);       if((fsd->PD.FAT_pd.BPB_boot_common.FATSz16) != 0)         FATSz = fsd->PD.FAT_pd.BPB_boot_common.FATSz16;       else         FATSz = fsd->PD.FAT_pd.BPB_boot_common.FATSz32Estim;              //read sector for Cluster       for(i=0;i<fsd->PD.FAT_pd.BPB_boot_common.NumFATs;i++)       { //scan all FAT tables in case of unavailable block         if ((ReturnCode=Get_SectorRel(SecBuff,FATEntry.Sector+i*FATSz,fsd)) == S_OK)           break;         else if(ReturnCode == E_FORCED_UNPLUG)                break;       }              if(ReturnCode != S_OK)       {       #ifdef DEBUGGING                  printf("Can't read sector, EOF!\n");#endif                  return ReturnCode;       }              switch(fsd->PD.FAT_pd.BPB_boot_common.FATType)       {         case 2: //FAT16#ifdef DSP                 *FATClusEntryVal = *((PACKED uint16*)&SecBuff[FATEntry.Offset]);#else                 *FATClusEntryVal = *((uint16*)&SecBuff[FATEntry.Offset]);#endif                 return S_OK;         case 0: //FAT32#ifdef DSP                 *FATClusEntryVal = (*((PACKED uint32*)&SecBuff[FATEntry.Offset])) & 0x0FFFFFFF;#else                 *FATClusEntryVal = (*((uint32*)&SecBuff[FATEntry.Offset])) & 0x0FFFFFFF;#endif                 return S_OK;         case 1: //FAT12                 if((FATEntry.Offset) == (fsd->PD.FAT_pd.BPB_boot_common.BytesPerSec-1))                 { //continue of FAT entry is in the next sector, so read it                   *FATClusEntryVal = SecBuff[fsd->PD.FAT_pd.BPB_boot_common.BytesPerSec-1];                   //read sector for next Cluster                   for(i=0;i<fsd->PD.FAT_pd.BPB_boot_common.NumFATs;i++)                   { //scan all FAT tables in case of unavailable block                     if ((ReturnCode=Get_SectorRel(SecBuff,FATEntry.Sector+1+i*FATSz,fsd)) == S_OK)                       break;                     else if(ReturnCode == E_FORCED_UNPLUG)                            break;                   }                                      if(ReturnCode != S_OK)                   {       #ifdef DEBUGGING                              printf("Can't read sector, EOF!\n");#endif                              return ReturnCode;                   }                   *FATClusEntryVal = (((uint32)(SecBuff[0]))<<8) | (*FATClusEntryVal);                 }                 else#ifdef DSP                   *FATClusEntryVal = *((PACKED uint16*)&SecBuff[FATEntry.Offset]);#else                   *FATClusEntryVal = *((uint16*)&SecBuff[FATEntry.Offset]);#endif                 if(Cluster&0x0001)                   *FATClusEntryVal = *FATClusEntryVal >> 4;    //Cluster number is ODD                 else                   *FATClusEntryVal = *FATClusEntryVal & 0x0FFF; //Cluster number is EVEN                 return S_OK;       }       return E_PARAMETER_OUT_OF_RANGE;  // should not come to this point}/*void FillExtTbl(FS_DESCRIPTOR *fsd, char ExtTblOEM[][4], uint32 ExtTblLen){    uint32 i,j,k;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -