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

📄 fs_configfat.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 3 页
字号:
 *   Search to find the smallest (reasonable) cluster size for the FAT file *   system. * * Input: *   fmt - Caller specified format parameters *   var - Other format parameters that are not caller specifiable. (Most *     set by mkfatfs_configfatfs()). * * Return: *    Zero on success; negated errno on failure * ****************************************************************************/static inline intmkfatfs_clustersearch(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var){  struct fat_config_s fatconfig[3];  ubyte  mxclustshift;  memset(fatconfig, 0, 3*sizeof(struct fat_config_s));  /* Select the reserved sector count for each FAT size */  if (fmt->ff_rsvdseccount)    {      fatconfig12.fc_rsvdseccount = fmt->ff_rsvdseccount;      fatconfig16.fc_rsvdseccount = fmt->ff_rsvdseccount;      if (fmt->ff_rsvdseccount < 2)        {          fvdbg("At least 2 reserved sectors needed by FAT32\n");          fatconfig32.fc_rsvdseccount = 2;        }      else        {          fatconfig32.fc_rsvdseccount = fmt->ff_rsvdseccount;        }    }  else    {      fatconfig12.fc_rsvdseccount = 1;      fatconfig16.fc_rsvdseccount = 1;      fatconfig32.fc_rsvdseccount = 32;    }  /* Determine the number of sectors needed by the root directory.   * This is a constant value, independent of cluster size for FAT12/16   */  if (var->fv_fattype != 32)    {      /* Calculate the number of sectors reqired to contain the selected       * number of root directory entries.  This value is save in the var       * structure but will be overwritten if FAT32 is selected.  FAT32 uses       * a cluster chain for the root directory, so the concept of the number       * of root directory entries does not apply to FAT32       */      var->fv_nrootdirsects =        ((fmt->ff_rootdirentries << DIR_SHIFT) + var->fv_sectorsize - 1) >> var->fv_sectshift;       /* The number of data sectors available (includes the fat itself)       * This value is a constant for FAT12/16, but not FAT32 because the       * size of the root directory cluster changes       */      fatconfig12.fc_navailsects =        fatconfig16.fc_navailsects =          fmt->ff_nsectors - var->fv_nrootdirsects - fatconfig12.fc_rsvdseccount;   }  /* Select an initial and terminal clustersize to use in the search (if these   * values were not provided by the caller)   */  mxclustshift = mkfatfs_clustersearchlimits(fmt, var);  do    {      fvdbg("Configuring with %d sectors/cluster...\n", 1 << fmt->ff_clustshift);       /* Check if FAT12 has not been excluded */      if (var->fv_fattype == 0 || var->fv_fattype == 12)        {          /* Try to configure a FAT12 filesystem with this cluster size */          if (mkfatfs_tryfat12(fmt, var, &fatconfig12) != 0)            {                {                  fvdbg("Cannot format FAT12 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);                  fatconfig12.fc_nfatsects = 0;                  fatconfig12.fc_nclusters = 0;                }            }        }      /* Check if FAT16 has not been excluded */      if (var->fv_fattype == 0 || var->fv_fattype == 16)        {          /* Try to configure a FAT16 filesystem with this cluster size */          if (mkfatfs_tryfat16(fmt, var, &fatconfig16) != 0)            {                {                  fvdbg("Cannot format FAT16 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);                  fatconfig16.fc_nfatsects = 0;                  fatconfig16.fc_nclusters = 0;                }            }        }      /* If either FAT12 or 16 was configured at this sector/cluster setting,       * then finish the configuration and break out now       */      if (fatconfig12.fc_nclusters || fatconfig16.fc_nclusters)        {          if ((!var->fv_fattype && fatconfig16.fc_nclusters > fatconfig12.fc_nclusters) ||              (var ->fv_fattype == 16))            {              /* The caller has selected FAT16 -OR- no FAT type has been selected, but               * the FAT16 selection has more clusters. Select FAT16.               */              mkfatfs_selectfat(16, fmt, var, &fatconfig16);            }          else            {              /* The caller has selected FAT12 -OR- no FAT type has been selected, but               * the FAT12 selected has more clusters.  Selected FAT12               */              mkfatfs_selectfat(12, fmt, var, &fatconfig12);            }         return OK;        }      /* Check if FAT32 has not been excluded */      if (var->fv_fattype == 0 || var->fv_fattype == 32)        {          /* The number of data sectors available (includes the fat itself)           * This value is a constant with respect to cluster sizefor FAT12/16, but not FAT32           * because the size of the root directory cluster changes with cluster size.           */          fatconfig32.fc_navailsects = fmt->ff_nsectors - (1 << fmt->ff_clustshift) - fatconfig32.fc_rsvdseccount;          /* Try to configure a FAT32 filesystem with this cluster size */          if (mkfatfs_tryfat32(fmt, var, &fatconfig32) != 0)            {                {                  fvdbg("Cannot format FAT32 at %u sectors/cluster\n", 1 << fmt->ff_clustshift);                  fatconfig32.fc_nfatsects = 0;                  fatconfig32.fc_nclusters = 0;                }            }          else            {              /* Select FAT32 if we have not already done so */              mkfatfs_selectfat(32, fmt, var, &fatconfig32);              return OK;            }        }      /* Otherwise, bump up the sectors/cluster for the next time around the loop. */      fmt->ff_clustshift++;    }  while (fmt->ff_clustshift <= mxclustshift);  return -ENFILE;}/**************************************************************************** * Global Functions ****************************************************************************//**************************************************************************** * Name: mkfatfs_configfatfs * * Description: *   Based on the geometry of the block device and upon the caller-selected *   values, configure the FAT filesystem for the device. * * Input: *    fmt  - Caller specified format parameters *    var  - Holds disk geomtry data.  Also, the location to return FAT *           configuration data * * Return: *    Zero on success; negated errno on failure * ****************************************************************************/int mkfatfs_configfatfs(FAR struct fat_format_s *fmt,                        FAR struct fat_var_s *var){  int ret;  /* Select the number of root directory entries (FAT12/16 only).  If FAT32 is selected,   * this value will be cleared later   */  if (!fmt->ff_rootdirentries)    {      /* The caller did not specify the number of root directory entries; use a default of 512. */      fmt->ff_rootdirentries = 512;    }  /* Search to determine the smallest (reasonable) cluster size.  A by-product   * of this search will be the selection of the FAT size (12/16/32) if the   * caller has not specified the FAT size   */  ret = mkfatfs_clustersearch(fmt, var);  if (ret < 0)    {       fdbg("Failed to set cluster size\n");       return ret;    }  /* Perform FAT specific initialization */  /* Set up boot jump assuming FAT 12/16 offset to bootcode */  var->fv_jump[0]      = OPCODE_JMP_REL8;  var->fv_jump[2]      = OPCODE_NOP;  var->fv_bootcode     = g_bootcodeblob;  var->fv_bootcodesize = sizeof(g_bootcodeblob);  if (var->fv_fattype != 32)    {      /* Set up additional, non-zero FAT12/16 fields */      /* Patch in the correct offset to the boot code */       var->fv_jump[1]   = BS16_BOOTCODE - 2;      g_bootcodeblob[3] = BS16_BOOTCODE + BOOTCODE_MSGOFFSET;    }  else    {      /* Patch in the correct offset to the boot code */      var->fv_jump[1]   = BS32_BOOTCODE - 2;      g_bootcodeblob[3] = BS32_BOOTCODE + BOOTCODE_MSGOFFSET;      /* The root directory is a cluster chain... its is initialize size is one cluster */        var->fv_nrootdirsects = 1 << fmt->ff_clustshift;      /* The number of reported root directory entries should should be zero for       * FAT32 because the root directory is a cluster chain.       */      fmt->ff_rootdirentries = 0;      /* Verify the caller's backupboot selection */      if (fmt->ff_backupboot <= 1 || fmt->ff_backupboot >= fmt->ff_rsvdseccount)        {          fdbg("Invalid backup boot sector: %d\n", fmt->ff_backupboot);          fmt->ff_backupboot = 0;        }     /* Check if the caller has selected a location for the backup boot record */      if (!fmt->ff_backupboot)        {          /* There must be reserved sectors in order to have a backup boot sector */          if (fmt->ff_rsvdseccount > 0 && fmt->ff_rsvdseccount >= 2)            {              /* Sector 0 is the MBR; 1... ff_rsvdseccount are reserved.  Try the next               * the last reserved sector.               */              fmt->ff_backupboot = fmt->ff_rsvdseccount - 1;              if (fmt->ff_backupboot > 6)                {                  /* Limit the location to within the first 7 */                  fmt->ff_backupboot = 6;                }            }        }    }  /* Report the selected fat type */  fmt->ff_fattype = var->fv_fattype;  /* Describe the configured filesystem */#ifdef CONFIG_DEBUG  fdbg("Sector size:          %d bytes\n", var->fv_sectorsize);  fdbg("Number of sectors:    %d sectors\n", fmt->ff_nsectors);  fdbg("FAT size:             %d bits\n", var->fv_fattype);  fdbg("Number FATs:          %d\n", fmt->ff_nfats);  fdbg("Sectors per cluster:  %d sectors\n", 1 << fmt->ff_clustshift);  fdbg("FS size:              %d sectors\n", var->fv_nfatsects);  fdbg("                      %d clusters\n", var->fv_nclusters);  if (var->fv_fattype != 32)    {       fdbg("Root directory slots: %d\n", fmt->ff_rootdirentries);    }  fdbg("Volume ID:            %08x\n", fmt->ff_volumeid);  fdbg("Volume Label:         \"%c%c%c%c%c%c%c%c%c%c%c\"\n",    fmt->ff_volumelabel[0], fmt->ff_volumelabel[1], fmt->ff_volumelabel[2],     fmt->ff_volumelabel[3], fmt->ff_volumelabel[4], fmt->ff_volumelabel[5],     fmt->ff_volumelabel[6], fmt->ff_volumelabel[7], fmt->ff_volumelabel[8],     fmt->ff_volumelabel[9], fmt->ff_volumelabel[10]);#endif  return OK;}

⌨️ 快捷键说明

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