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

📄 fs_fat32util.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
 ****************************************************************************/int fat_dircreate(struct fat_mountpt_s *fs, struct fat_dirinfo_s *dirinfo){  ubyte  *direntry;  uint32  time;  int     ret;  /* Set up the directory entry */  ret = fat_allocatedirentry(fs, dirinfo);  if (ret != OK)    {      /* Failed to set up directory entry */      return ret;    }  /* Initialize the 32-byte directory entry */  direntry = dirinfo->fd_entry;  memset(direntry, 0, 32);  /* Directory name info */  memcpy(&direntry[DIR_NAME], dirinfo->fd_name, 8+3);#ifdef CONFIG_FLAT_LCNAMES  DIR_PUTNTRES(dirinfo->fd_entry, dirinfo->fd_ntflags);#else  DIR_PUTNTRES(dirinfo->fd_entry, 0);#endif  /* ARCHIVE attribute, write time, creation time */  DIR_PUTATTRIBUTES(dirinfo->fd_entry, FATATTR_ARCHIVE);   time = fat_systime2fattime();  DIR_PUTWRTTIME(dirinfo->fd_entry, time & 0xffff);  DIR_PUTCRTIME(dirinfo->fd_entry, time & 0xffff);  DIR_PUTWRTDATE(dirinfo->fd_entry, time >> 16);  DIR_PUTCRDATE(dirinfo->fd_entry, time >> 16);  fs->fs_dirty = TRUE;  return OK;}/**************************************************************************** * Name: fat_remove * * Desciption: Remove a directory or file from the file system.  This *   implements both rmdir() and unlink(). * ****************************************************************************/int fat_remove(struct fat_mountpt_s *fs, const char *relpath, boolean directory){  struct fat_dirinfo_s dirinfo;  uint32  dircluster;  size_t  dirsector;  int     ret;  /* Find the directory entry referring to the entry to be deleted */  ret = fat_finddirentry(fs, &dirinfo, relpath);  if (ret != OK)    {      /* No such path */      return -ENOENT;    }  /* Check if this is a FAT12/16 root directory */  if (dirinfo.fd_entry == NULL)    {      /* The root directory cannot be removed */      return -EPERM;    }  /* The object has to have write access to be deleted */  if ((DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_READONLY) != 0)    {      /* It is a read-only entry */      return -EACCES;    }  /* Get the directory sector and cluster containing the   * entry to be deleted   */  dirsector  = fs->fs_currentsector;  dircluster =      ((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |      DIR_GETFSTCLUSTLO(dirinfo.fd_entry);  /* Is this entry a directory? */  if (DIR_GETATTRIBUTES(dirinfo.fd_entry) & FATATTR_DIRECTORY)    {      /* It is a sub-directory. Check if we are be asked to remove       * a directory or a file.       */      if (!directory)        {          /* We are asked to delete a file */          return -EISDIR;        }      /* We are asked to delete a directory. Check if this       * sub-directory is empty       */      dirinfo.dir.fd_currcluster = dircluster;      dirinfo.dir.fd_currsector  = fat_cluster2sector(fs, dircluster);      dirinfo.dir.fd_index       = 2;      /* Loop until either (1) an entry is found in the directory       * (error), (2) the directory is found to be empty, or (3) some       * error occurs.       */      for (;;)        {          unsigned int subdirindex;          ubyte       *subdirentry;          /* Make sure that the sector containing the of the           * subdirectory sector is in the cache           */          ret = fat_fscacheread(fs, dirinfo.dir.fd_currsector);          if (ret < 0)            {              return ret;            }          /* Get a reference to the next entry in the directory */          subdirindex = (dirinfo.dir.fd_index & DIRSEC_NDXMASK(fs)) * 32;          subdirentry = &fs->fs_buffer[subdirindex];          /* Is this the last entry in the direcory? */          if (subdirentry[DIR_NAME] == DIR0_ALLEMPTY)            {              /* Yes then the directory is empty.  Break out of the               * loop and delete the directory.               */              break;            }          /* Check if the next entry refers to a file or directory */          if (subdirentry[DIR_NAME] != DIR0_EMPTY &&              !(DIR_GETATTRIBUTES(subdirentry) & FATATTR_VOLUMEID))            {              /* The directory is not empty */              return -ENOTEMPTY;            }          /* Get the next directgory entry */          ret = fat_nextdirentry(fs, &dirinfo.dir);          if (ret < 0)            {              return ret;            }        }    }  else    {      /* It is a file. Check if we are be asked to remove a directory       * or a file.       */      if (directory)        {          /* We are asked to remove a directory */          return -ENOTDIR;        }    }  /* Make sure that the directory containing the entry to be deleted is   * in the cache.   */  ret = fat_fscacheread(fs, dirsector);  if (ret < 0)    {      return ret;    }  /* Mark the directory entry 'deleted' */  dirinfo.fd_entry[DIR_NAME] = DIR0_EMPTY;  fs->fs_dirty = TRUE;  /* And remove the cluster chain making up the subdirectory */  ret = fat_removechain(fs, dircluster);  if (ret < 0)    {      return ret;    }  /* Update the FSINFO sector (FAT32) */  ret = fat_updatefsinfo(fs);  if (ret < 0)    {      return ret;    }  return OK;}/**************************************************************************** * Name: fat_fscacheflush * * Desciption: Flush any dirty sector if fs_buffer as necessary * ****************************************************************************/int fat_fscacheflush(struct fat_mountpt_s *fs){  int ret;  /* Check if the fs_buffer is dirty.  In this case, we will write back the   * contents of fs_buffer.   */  if (fs->fs_dirty)  {      /* Write the dirty sector */      ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);      if (ret < 0)      {          return ret;      }      /* Does the sector lie in the FAT region? */      if (fs->fs_currentsector < fs->fs_fatbase + fs->fs_nfatsects)      {          /* Yes, then make the change in the FAT copy as well */          int i;          for (i = fs->fs_fatnumfats; i >= 2; i--)          {               fs->fs_currentsector += fs->fs_nfatsects;              ret = fat_hwwrite(fs, fs->fs_buffer, fs->fs_currentsector, 1);              if (ret < 0)              {                  return ret;              }          }      }      /* No longer dirty */      fs->fs_dirty = FALSE;  }  return OK;}/**************************************************************************** * Name: fat_fscacheread * * Desciption: Read the specified sector into the sector cache, flushing any *   existing dirty sectors as necessary. * ****************************************************************************/int fat_fscacheread(struct fat_mountpt_s *fs, size_t sector){  int ret;  /* fs->fs_currentsector holds the current sector that is buffered in   * fs->fs_buffer. If the requested sector is the same as this sector, then   * we do nothing. Otherwise, we will have to read the new sector.   */    if (fs->fs_currentsector != sector)      {        /* We will need to read the new sector.  First, flush the cached         * sector if it is dirty.         */        ret = fat_fscacheflush(fs);        if (ret < 0)          {              return ret;          }        /* Then read the specified sector into the cache */        ret = fat_hwread(fs, fs->fs_buffer, sector, 1);        if (ret < 0)          {            return ret;          }        /* Update the cached sector number */        fs->fs_currentsector = sector;    }    return OK;}/**************************************************************************** * Name: fat_ffcacheflush * * Desciption: Flush any dirty sectors as necessary * ****************************************************************************/int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff){  int ret;  /* Check if the ff_buffer is dirty.  In this case, we will write back the   * contents of ff_buffer.   */  if (ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID))  {      /* Write the dirty sector */      ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_currentsector, 1);      if (ret < 0)      {          return ret;      }      /* No longer dirty */      ff->ff_bflags &= ~FFBUFF_DIRTY;  }  return OK;}/**************************************************************************** * Name: fat_ffcacheread * * Desciption: Read the specified sector into the sector cache, flushing any *   existing dirty sectors as necessary. * ****************************************************************************/int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sector){  int ret;  /* ff->ff_currentsector holds the current sector that is buffered in   * ff->ff_buffer. If the requested sector is the same as this sector, then   * we do nothing. Otherwise, we will have to read the new sector.   */  if (ff->ff_currentsector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0)      {        /* We will need to read the new sector.  First, flush the cached         * sector if it is dirty.         */        ret = fat_ffcacheflush(fs, ff);        if (ret < 0)          {              return ret;          }        /* Then read the specified sector into the cache */        ret = fat_hwread(fs, ff->ff_buffer, sector, 1);        if (ret < 0)          {            return ret;          }        /* Update the cached sector number */        ff->ff_currentsector = sector;        ff->ff_bflags |= FFBUFF_VALID;    }    return OK;}/**************************************************************************** * Name: fat_ffcacheread * * Desciption: Invalidate the current file buffer contents * ****************************************************************************/int fat_ffcacheinvalidate(struct fat_mountpt_s *fs, struct fat_file_s *ff){  int ret;  /* Is there anything valid in the buffer now? */  if ((ff->ff_bflags & FFBUFF_VALID) != 0)      {        /* We will invalidate the buffered sector */        ret = fat_ffcacheflush(fs, ff);        if (ret < 0)          {              return ret;          }        /* Then discard the current cache contents */        ff->ff_bflags &= ~FFBUFF_VALID;    }    return OK;}/**************************************************************************** * Name: fat_updatefsinfo * * Desciption: Flush evertyhing buffered for the mountpoint and update *   the FSINFO sector, if appropriate * ****************************************************************************/int fat_updatefsinfo(struct fat_mountpt_s *fs){  int ret;  /* Flush the fs_buffer if it is dirty */  ret = fat_fscacheflush(fs);  if (ret == OK)    {      /* The FSINFO sector only has to be update for the case of a FAT32 file       * system.  Check if the file system type.. If this is a FAT32 file       * system then the fs_fsidirty flag will indicate if the FSINFO sector       * needs to be re-written.       */      if (fs->fs_type == FSTYPE_FAT32 && fs->fs_fsidirty)        {          /* Create an image of the FSINFO sector in the fs_buffer */          memset(fs->fs_buffer, 0, fs->fs_hwsectorsize);          FSI_PUTLEADSIG(fs->fs_buffer, 0x41615252);          FSI_PUTSTRUCTSIG(fs->fs_buffer, 0x61417272);          FSI_PUTFREECOUNT(fs->fs_buffer, fs->fs_fsifreecount);          FSI_PUTNXTFREE(fs->fs_buffer, fs->fs_fsinextfree);          FSI_PUTTRAILSIG(fs->fs_buffer, BOOT_SIGNATURE32);          /* Then flush this to disk */          fs->fs_currentsector = fs->fs_fsinfo;          fs->fs_dirty         = TRUE; 

⌨️ 快捷键说明

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