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

📄 fs_fat32util.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
                  startsector >>= 4;                }              else                {                  /* Even.. take the LS 12-bits */                  startsector &= 0x0fff;                }              return startsector;            }          case FSTYPE_FAT16 :            {              unsigned int fatoffset = 2 * clusterno;              size_t       fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              unsigned int fatindex  = fatoffset & SEC_NDXMASK(fs);              if (fat_fscacheread(fs, fatsector) < 0)                {                  /* Read error */                  break;                }              return FAT_GETFAT16(fs->fs_buffer, fatindex);            }          case FSTYPE_FAT32 :            {              unsigned int fatoffset = 4 * clusterno;              size_t       fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              unsigned int fatindex  = fatoffset & SEC_NDXMASK(fs);              if (fat_fscacheread(fs, fatsector) < 0)                {                  /* Read error */                  break;                }              return FAT_GETFAT16(fs->fs_buffer, fatindex) & 0x0fffffff;            }          default:              break;        }    }  /* There is no cluster information, or an error occured */  return (ssize_t)-EINVAL;}/**************************************************************************** * Name: fat_putcluster * * Desciption: Write a new cluster start sector into the FAT * ****************************************************************************/int fat_putcluster(struct fat_mountpt_s *fs, uint32 clusterno, size_t startsector){  /* Verify that the cluster number is within range.  Zero erases the cluster. */  if (clusterno == 0 || (clusterno >= 2 && clusterno < fs->fs_nclusters))    {      /* Okay.. Write the next cluster into the FAT.  The way we will do       * this depends on the type of FAT filesystm we are dealing with.       */      switch (fs->fs_type)        {          case FSTYPE_FAT12 :            {              size_t       fatsector;              unsigned int fatoffset;              unsigned int fatindex;              ubyte        value;              /* FAT12 is more complex because it has 12-bits (1.5 bytes)               * per FAT entry. Get the offset to the first byte:               */              fatoffset = (clusterno * 3) / 2;              fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              /* Make sure that the sector at this offset is in the cache */              if (fat_fscacheread(fs, fatsector)< 0)                {                  /* Read error */                  break;                }              /* Output the LS byte first handling the 12-bit alignment within               * the 16-bits               */              fatindex = fatoffset & SEC_NDXMASK(fs);              if ((clusterno & 1) != 0)                {                  value = (fs->fs_buffer[fatindex] & 0x0f) | startsector << 4;                }              else                {                  value = (ubyte)startsector;                }              fs->fs_buffer[fatindex] = value;              /* With FAT12, the second byte of the cluster number may lie in               * a different sector than the first byte.               */              fatindex++;              if (fatindex >= fs->fs_hwsectorsize)                {                  /* Read the next sector */                  fatsector++;                  fatindex = 0;                  /* Set the dirty flag to make sure the sector that we                   * just modified is written out.                   */                  fs->fs_dirty = TRUE;                  if (fat_fscacheread(fs, fatsector) < 0)                    {                      /* Read error */                      break;                    }                }              /* Output the MS byte first handling the 12-bit alignment within               * the 16-bits               */              if ((clusterno & 1) != 0)                {                  value = (ubyte)(startsector >> 4);                }              else                {                  value = (fs->fs_buffer[fatindex] & 0xf0) | (startsector & 0x0f);                }              fs->fs_buffer[fatindex] = value;            }          break;          case FSTYPE_FAT16 :            {              unsigned int fatoffset = 2 * clusterno;              size_t       fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              unsigned int fatindex  = fatoffset & SEC_NDXMASK(fs);              if (fat_fscacheread(fs, fatsector) < 0)                {                  /* Read error */                  break;                }              FAT_PUTFAT16(fs->fs_buffer, fatindex, startsector & 0xffff);            }          break;          case FSTYPE_FAT32 :            {              unsigned int fatoffset = 4 * clusterno;              size_t       fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              unsigned int fatindex  = fatoffset & SEC_NDXMASK(fs);              if (fat_fscacheread(fs, fatsector) < 0)                {                  /* Read error */                  break;                }              FAT_PUTFAT32(fs->fs_buffer, fatindex, startsector & 0x0fffffff);            }          break;          default:              return -EINVAL;        }      /* Mark the modified sector as "dirty" and return success */      fs->fs_dirty = 1;      return OK;    }  return -EINVAL;}/**************************************************************************** * Name: fat_removechain * * Desciption: Remove an entire chain of clusters, starting with 'cluster' * ****************************************************************************/int fat_removechain(struct fat_mountpt_s *fs, uint32 cluster){  sint32 nextcluster;  int    ret;  /* Loop while there are clusters in the chain */  while (cluster >= 2 && cluster < fs->fs_nclusters)    {      /* Get the next cluster after the current one */      nextcluster = fat_getcluster(fs, cluster);      if (nextcluster < 0)        {          /* Error! */          return nextcluster;        }      /* Then nullify current cluster -- removing it from the chain */      ret = fat_putcluster(fs, cluster, 0);      if (ret < 0)        {          return ret;        }      /* Update FSINFINFO data */      if (fs->fs_fsifreecount != 0xffffffff)        {          fs->fs_fsifreecount++;          fs->fs_fsidirty = 1;        }      /* Then set up to remove the next cluster */      cluster = nextcluster;  }  return OK;}/**************************************************************************** * Name: fat_extendchain * * Desciption: Add a new cluster to the chain following cluster (if cluster *   is non-NULL).  if cluster is zero, then a new chain is created. * * Return: <0:error, 0: no free cluster, >=2: new cluster number * ****************************************************************************/sint32 fat_extendchain(struct fat_mountpt_s *fs, uint32 cluster){  ssize_t startsector;  uint32  newcluster;  uint32  startcluster;  int     ret;  /* The special value 0 is used when the new chain should start */  if (cluster == 0)    {      /* The FSINFO NextFree entry should be a good starting point       * in the search for a new cluster       */      startcluster = fs->fs_fsinextfree;      if (startcluster == 0 || startcluster >= fs->fs_nclusters)        {          /* But it is bad.. we have to start at the beginning */          startcluster = 1;        }    }  else    {      /* We are extending an existing chain. Verify that this       * is a valid cluster by examining its start sector.       */      startsector = fat_getcluster(fs, cluster);      if (startsector < 0)        {          /* An error occurred, return the error value */          return startsector;        }      else if (startsector < 2)        {          /* Oops.. this cluster does not exist. */          return 0;        }      else if (startsector < fs->fs_nclusters)        {          /* It is already followed by next cluster */          return startsector;        }      /* Okay.. it checks out */      startcluster = cluster;    }  /* Loop until (1) we discover that there are not free clusters   * (return 0), an errors occurs (return -errno), or (3) we find   * the next cluster (return the new cluster number).   */  newcluster = startcluster;  for (;;)    {      /* Examine the next cluster in the FAT */      newcluster++;      if (newcluster >= fs->fs_nclusters)        {          /* If we hit the end of the available clusters, then           * wrap back to the beginning because we might have           * started at a non-optimal place.  But don't continue           * past the start cluster.           */          newcluster = 2;          if (newcluster > startcluster)            {              /* We are back past the starting cluster, then there               * is no free cluster.               */              return 0;            }        }      /* We have a candidate cluster.  Check if the cluster number is       * mapped to a group of sectors.       */      startsector = fat_getcluster(fs, newcluster);      if (startsector == 0)        {          /* Found have found a free cluster break out*/          break;        }      else if (startsector < 0)        {          /* Some error occurred, return the error number */          return startsector;        }      /* We wrap all the back to the starting cluster?  If so, then       * there are no free clusters.       */      if (newcluster == startcluster)        {          return 0;        }    }  /* We get here only if we break out with an available cluster   * number in 'newcluster'  Now mark that cluster as in-use.   */  ret = fat_putcluster(fs, newcluster, 0x0fffffff);  if (ret < 0)    {      /* An error occurred */       return ret;    }  /* And link if to the start cluster (if any)*/  if (cluster)    {      /* There is a start cluster -- link it */      ret = fat_putcluster(fs, cluster, newcluster);      if (ret < 0)        {          return ret;        }    }  /* And update the FINSINFO for the next time we have to search */  fs->fs_fsinextfree = newcluster;  if (fs->fs_fsifreecount != 0xffffffff)    {      fs->fs_fsifreecount--;      fs->fs_fsidirty = 1;    }  /* Return then number of the new cluster that was added to the chain */  return newcluster;}/**************************************************************************** * Name: fat_nextdirentry * * Desciption: Read the next directory entry from the sector in cache, *   reading the next sector(s) in the cluster as necessary. * ****************************************************************************/int fat_nextdirentry(struct fat_mountpt_s *fs, struct fs_fatdir_s *dir){  unsigned int cluster;  unsigned int ndx;  /* Increment the index to the next 32-byte directory entry */  ndx = dir->fd_index + 1;  /* Check if all of the directory entries in this sectory have   * been examined.   */  if ((ndx & (DIRSEC_NDIRS(fs)-1)) == 0)    {      /* Yes, then we will have to read the next sector */      dir->fd_currsector++;      /* For FAT12/16, the root directory is a group of sectors relative       * to the first sector of the fat volume.       */      if (!dir->fd_currcluster)        {          /* For FAT12/16, the boot record tells us number of 32-bit directories           * that are contained in the root directory.  This should correspond to           * an even number of sectors.           */          if (ndx >= fs->fs_rootentcnt)            {              /* When we index past this count, we have examined all of the entries in               * the root directory.               */              return ERROR;            }        }      else        {          /* Not a FAT12/16 root directory, check if we have examined the entire           * cluster comprising the directory.           *           * The current sector within the cluster is the entry number divided           * byte the number of entries per sector           */          int sector = ndx / DIRSEC_NDIRS(fs);          /* We are finished with the cluster when the last sector of the cluster           * has been examined.           */          if ((sector & (fs->fs_fatsecperclus-1)) == 0)            {              /* Get next cluster */              cluster = fat_getcluster(fs, dir->fd_currcluster);              /* Check if a valid cluster was obtained. */              if (cluster < 2 || cluster >= fs->fs_nclusters)                {                  /* No, we have probably reached the end of the cluster list */                  return ERROR;                }              /* Initialize for new cluster */

⌨️ 快捷键说明

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