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

📄 fat.lst

📁 Philips LPC2138 Demo Application with Keil C
💻 LST
📖 第 1 页 / 共 5 页
字号:
  254   1          euint8 hb,lb;
  255   1          euint16 offset;
ARM COMPILER V2.42,  fat                                                                   27/03/06  10:45:49  PAGE 5   

  256   1          euint32 nextcluster=0;
  257   1          
  258   1          switch(fs->type)
  259   1          {
  260   2              case FAT12:
  261   2                  offset = ((cluster_addr%1024)*3/2)%512;
  262   2                  hb = buf[offset];
  263   2                  if(offset == 511){
  264   3                      buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READONLY);
  265   3                      lb = buf2[0];
  266   3                      part_relSect(fs->part,buf2);
  267   3                  }else{
  268   3                      lb = buf[offset + 1];
  269   3                  }
  270   2                  if(cluster_addr%2==0){
  271   3                      nextcluster = ( ((lb&0x0F)<<8) + (hb) );
  272   3                  }else{
  273   3                      nextcluster = ( (lb<<4) + (hb>>4) );
  274   3                  }
  275   2                  break;
  276   2              case FAT16:
  277   2                  offset=cluster_addr%256;
  278   2                  nextcluster = *((euint16*)buf + offset);
  279   2                  break;
  280   2              case FAT32:
  281   2                  offset=cluster_addr%128;
  282   2                  nextcluster = *((euint32*)buf + offset);
  283   2                  break;
  284   2          }
  285   1          return(nextcluster);
  286   1      }
  287          /*****************************************************************************/ 
  288          
  289          /* ****************************************************************************  
  290           * void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint
             -8* buf)
  291           * Description: This function fills in a fat entry. The entry is cluster_addr and the
  292           * data entered is next_cluster_addr. This function is also given a *buf, so it does
  293           * not write the data itself, except in the case of FAT 12 cross sector data, where
  294           * the second sector is handled by this function.
  295           * Return value:
  296          */
  297          void fat_setNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr,euint8* 
             -buf)
  298          {
  299   1          euint16 offset;
  300   1          euint8 *buf2;
  301   1              
  302   1          switch(fs->type)
  303   1          {
  304   2              case FAT12:
  305   2                  offset = ((cluster_addr%1024)*3/2)%512;
  306   2                  if(offset == 511){
  307   3                      if(cluster_addr%2==0){
  308   4                          buf[offset]=next_cluster_addr&0xFF;
  309   4                      }else{
  310   4                          buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
  311   4                      }
  312   3                      buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READWRITE);
  313   3                      if(cluster_addr%2==0){
  314   4                          buf2[0]=(buf2[0]&0xF0)+((next_cluster_addr>>8)&0xF);
  315   4                      }else{
  316   4                          buf2[0]=(next_cluster_addr>>4)&0xFF;
  317   4                      }
  318   3                      part_relSect(fs->part,buf2);
  319   3                  }else{
ARM COMPILER V2.42,  fat                                                                   27/03/06  10:45:49  PAGE 6   

  320   3                      if(cluster_addr%2==0){
  321   4                          buf[offset]=next_cluster_addr&0xFF;
  322   4                          buf[offset+1]=(buf[offset+1]&0xF0)+((next_cluster_addr>>8)&0xF);
  323   4                      }else{
  324   4                          buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
  325   4                          buf[offset+1]=(next_cluster_addr>>4)&0xFF;
  326   4                      }
  327   3                  }
  328   2                  break;
  329   2              case FAT16:
  330   2                  offset=cluster_addr%256;
  331   2                  *((euint16*)buf+offset)=next_cluster_addr;
  332   2                  break;
  333   2              case FAT32:
  334   2                  offset=cluster_addr%128;
  335   2                  *((euint32*)buf+offset)=next_cluster_addr;
  336   2                  break;
  337   2          }
  338   1      }
  339          /*****************************************************************************/
  340          
  341          /* ****************************************************************************  
  342           * esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache)
  343           * Description: This function is to advance the clusterchain of a Cache.
  344           * First, the function verifies if the Cache is valid. It could correct it if it 
  345           * is not, but this is not done at the time. If the cachen is valid, the next step is
  346           * to see what the next cluster is, if this is the End of Clustermark, the cache is
  347           * updated to know the lastcluster but will remain untouched otherwise. -1 is returned.
  348           * If there are more clusters the function scans the rest of the chain until the next
  349           * cluster is no longer lineair, or until it has run out of fat data (only 1 sector) is
  350           * examined, namely the one fetched to check for EoC.
  351           * With lineair is meant that logical cluster n+1 should be 1 more than logical cluster n
  352           * at the disc level.
  353           * Return value: 0 on success, or -1 when EoC.
  354          */
  355          esint16 fat_getNextClusterChain(FileSystem *fs, ClusterChain *Cache)
  356          {
  357   1          euint32 sect,lr,nlr,dc;
  358   1          esint16 lin=0;
  359   1          euint8 *buf;
  360   1      
  361   1          if(Cache->DiscCluster==0)
  362   1          {
  363   2              return(-1);
  364   2          }
  365   1      
  366   1          sect=fat_getSectorAddressFatEntry(fs,Cache->DiscCluster);
  367   1          buf=part_getSect(fs->part,sect,IOM_MODE_READONLY);
  368   1          dc=fat_getNextClusterAddressWBuf(fs,Cache->DiscCluster,buf);
  369   1          if(fat_isEocMarker(fs,dc))
  370   1          {
  371   2              Cache->LastCluster=Cache->DiscCluster;
  372   2              part_relSect(fs->part,buf);
  373   2              return(-1);
  374   2          }
  375   1          
  376   1          Cache->DiscCluster=dc;
  377   1          Cache->LogicCluster++;
  378   1              
  379   1          lr=Cache->DiscCluster-1;
  380   1          nlr=lr+1;
  381   1          
  382   1          while(nlr-1==lr && fat_getSectorAddressFatEntry(fs,nlr)==sect)
  383   1          {
  384   2              lr=nlr;
  385   2              nlr=fat_getNextClusterAddressWBuf(fs,lr,buf);
ARM COMPILER V2.42,  fat                                                                   27/03/06  10:45:49  PAGE 7   

  386   2              lin++;  
  387   2          }
  388   1          
  389   1          Cache->Linear=lin-1<0?0:lin-1;
  390   1          
  391   1          part_relSect(fs->part,buf);
  392   1          return(0);
  393   1      }
  394          /*****************************************************************************/
  395          
  396          
  397          /* ****************************************************************************  
  398           * esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster)
  399           * Description: This function is used to follow clusterchains. When called it will convert
  400           * a logical cluster, to a disc cluster, using a Cache object. All it does is call
  401           * getNextClusterChain in the proper manner, and rewind clusterchains if required.
  402           * It is NOT recommended to go backwards in clusterchains, since this will require
  403           * scanning the entire chain every time.
  404           * Return value: 0 on success and -1 on failure (meaning out of bounds).
  405          */
  406          esint16 fat_LogicToDiscCluster(FileSystem *fs, ClusterChain *Cache,euint32 logiccluster)
  407          {
  408   1          if(logiccluster<Cache->LogicCluster || Cache->DiscCluster==0){
  409   2              Cache->LogicCluster=0;
  410   2              Cache->DiscCluster=Cache->FirstCluster;
  411   2              Cache->Linear=0;
  412   2          }
  413   1          
  414   1          if(Cache->LogicCluster==logiccluster){
  415   2              return(0);
  416   2          }
  417   1          
  418   1          while(Cache->LogicCluster!=logiccluster)
  419   1          {
  420   2              if(Cache->Linear!=0)
  421   2              {
  422   3                  Cache->Linear--;
  423   3                  Cache->LogicCluster++;
  424   3                  Cache->DiscCluster++;
  425   3              }
  426   2              else
  427   2              {
  428   3                  if((fat_getNextClusterChain(fs,Cache))!=0){
  429   4                      return(-1);
  430   4                  }
  431   3              }
  432   2          }
  433   1          return(0);
  434   1      }
  435          /*****************************************************************************/
  436          
  437          /* ****************************************************************************  
  438           * eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters)
  439           * Description: This function extends a clusterchain by num_clusters. It returns the
  440           * number of clusters it *failed* to allocate. 
  441           * Return value: 0 on success, all other values are the number of clusters it could
  442           * not allocate.
  443          */
  444          eint16 fat_allocClusterChain(FileSystem *fs,ClusterChain *Cache,euint32 num_clusters)
  445          {
  446   1          euint32 cc,ncl=num_clusters,lc;
  447   1          euint8 *bufa=0,*bufb=0;
  448   1          euint8  overflow=0;
  449   1      
  450   1          if(Cache->FirstCluster<=1)return(num_clusters);
  451   1          
ARM COMPILER V2.42,  fat                                                                   27/03/06  10:45:49  PAGE 8   

  452   1          lc=fs_getLastCluster(fs,Cache);
  453   1          cc=lc;
  454   1          
  455   1          while(ncl > 0){
  456   2              cc++;
  457   2              if(cc>=fs->DataClusterCount+1){
  458   3                  if(overflow){
  459   4                      bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
  460   4                      fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);
  461   4                      Cache->LastCluster=lc;
  462   4                      part_relSect(fs->part,bufa);
  463   4                      fs->FreeClusterCount-=num_clusters-ncl;
  464   4                      return(num_clusters-ncl);
  465   4                  }
  466   3                  cc=2;
  467   3                  overflow++;
  468   3              }
  469   2              bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cc),IOM_MODE_READONLY);
  470   2              if(fat_getNextClusterAddressWBuf(fs,cc,bufa)==0){
  471   3                  bufb=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
  472   3                  fat_setNextClusterAddressWBuf(fs,lc,cc,bufb);
  473   3                  part_relSect(fs->part,bufb);
  474   3                  ncl--;
  475   3                  lc=cc;
  476   3              }
  477   2              part_relSect(fs->part,bufa);
  478   2              if(ncl==0){
  479   3                  bufa=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,lc),IOM_MODE_READWRITE);
  480   3                  fat_setNextClusterAddressWBuf(fs,lc,fat_giveEocMarker(fs),bufa);
  481   3                  Cache->LastCluster=lc;
  482   3                  part_relSect(fs->part,bufa);
  483   3              }
  484   2          }
  485   1          if(Cache->ClusterCount)Cache->ClusterCount+=num_clusters;
  486   1          return(0);
  487   1      }
  488          
  489          /* ****************************************************************************  
  490           * eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache)
  491           * Description: This function removes a clusterchain. Starting at FirstCluster
  492           * it follows the chain until the end, resetting all values to 0.
  493           * Return value: 0 on success.
  494          */
  495          eint16 fat_unlinkClusterChain(FileSystem *fs,ClusterChain *Cache)
  496          {
  497   1          euint32 c,tbd=0;
  498   1          
  499   1          Cache->LogicCluster=0;
  500   1          Cache->DiscCluster=Cache->FirstCluster;
  501   1          
  502   1          c=0;
  503   1          
  504   1          while(!fat_LogicToDiscCluster(fs,Cache,c++)){
  505   2              if(tbd!=0){
  506   3                  fat_setNextClusterAddress(fs,tbd,0);
  507   3              }
  508   2              tbd=Cache->DiscCluster;
  509   2          }
  510   1          fat_setNextClusterAddress(fs,Cache->DiscCluster,0);
  511   1          fs->FreeClusterCount+=c;    
  512   1          return(0);
  513   1      }

⌨️ 快捷键说明

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