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

📄 fsintrnl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  int s = *sp;

  /*-------------------------------------------------------------------*/
  /* Keep looping until either we go past maximum value or we find a   */
  /* used sector.                                                      */
  /*-------------------------------------------------------------------*/
  while (++sector)
  {
    /*-----------------------------------------------------------------*/
    /* If we've reached the end of a block in the erase set, move to   */
    /* next block.                                                     */
    /*-----------------------------------------------------------------*/
    if (sector == (Flash->erase_set[s] + 1) * Flash->block_sects)
    {
      /*---------------------------------------------------------------*/
      /* If no more blocks in erase set, no more used sectors.         */
      /*---------------------------------------------------------------*/
      if (++s >= Flash->set_blocks || Flash->erase_set[s] == -1)
        return (uint)-1;
      sector = Flash->erase_set[s] * Flash->block_sects;
    }

    /*-----------------------------------------------------------------*/
    /* If a used sector is found, stop and return it.                  */
    /*-----------------------------------------------------------------*/
    if (used_sect(sector))
      break;
  }
  *sp = s;
  return sector;
}

/***********************************************************************/
/*    to_offst: Transform a pointer into a ui32 offset so that it can  */
/*              be stored in flash                                     */
/*                                                                     */
/*       Input: entry = pointer to entry in the table                  */
/*                                                                     */
/*     Returns: offset equivalent of pointer                           */
/*                                                                     */
/***********************************************************************/
static ui32 to_offst(const void *entry)
{
  ui16 table_num = 1;
  FFSEnts *tbl;
  union
  {
    OffLoc entry_loc;
    ui32 result;
  } obj;

  /*-------------------------------------------------------------------*/
  /* For NULL pointers, return -1 as offset location.                  */
  /*-------------------------------------------------------------------*/
  if (entry == NULL)
    return (ui32)-1;

  /*-------------------------------------------------------------------*/
  /* Store the special value, REMOVED_LINK, as OFF_REMOVED_LINK.       */
  /*-------------------------------------------------------------------*/
  if (entry == (void *)REMOVED_LINK)
    return (OFF_REMOVED_LINK << 16) | OFF_REMOVED_LINK; /*lint !e648*/

  /*-------------------------------------------------------------------*/
  /* Figure out which table this entry belongs to.                     */
  /*-------------------------------------------------------------------*/
  for (tbl = Flash->files_tbl; tbl; tbl = tbl->next_tbl, ++table_num)
    if ((tbl->tbl + FNUM_ENT > (FFSEnt *)entry) &&
        (tbl->tbl <= (FFSEnt *)entry))
      break;

  /*-------------------------------------------------------------------*/
  /* The entry must belong to some table.                              */
  /*-------------------------------------------------------------------*/
  PfAssert(tbl);

  /*-------------------------------------------------------------------*/
  /* Figure out the offset within the table for this entry.            */
  /*-------------------------------------------------------------------*/
  obj.entry_loc.offset = (ui16)((FFSEnt *)entry - tbl->tbl);

  /*-------------------------------------------------------------------*/
  /* Return ui32 containing table number and entry offset.             */
  /*-------------------------------------------------------------------*/
  obj.entry_loc.sector = table_num;
  return obj.result;
}

/***********************************************************************/
/* count_ctrl_size: Count control info size (bytes and sectors)        */
/*                                                                     */
/*      Inputs: adjust_erase = flag to adjust erase set size           */
/*              check_recycle = flag to check recycles in adjust set   */
/*                                                                     */
/*     Returns: number of ctrl shorts to be checked against actual val */
/*                                                                     */
/***********************************************************************/
static ui32 count_ctrl_size(int adjust_erase, int check_recycle)
{
  ui32 table_size, i, ctrl_num_shorts, ctrl_size, ctrl_sects;
  ui32 free_ctrl_sects, incr;
  ui16 sector, last_in_segment, curr_sect, next_sect;

  /*-------------------------------------------------------------------*/
  /* Figure out how much space is needed to store the sectors table.   */
  /* Start with the free list.                                         */
  /*-------------------------------------------------------------------*/
  ctrl_num_shorts = 2;
  for (sector = Flash->free_sect;; sector = next_sect)
  {
    /*-----------------------------------------------------------------*/
    /* Determine current free block.                                   */
    /*-----------------------------------------------------------------*/
    i = sector / Flash->block_sects;

    /*-----------------------------------------------------------------*/
    /* Determine first sector in next free block.                      */
    /*-----------------------------------------------------------------*/
    next_sect = Flash->sect_tbl[(i + 1) * Flash->block_sects - 1].next;

    /*-----------------------------------------------------------------*/
    /* If no more blocks, stop and account for current segment.        */
    /*-----------------------------------------------------------------*/
    if (next_sect == FLAST_SECT)
    {
      ctrl_num_shorts += 2;
      break;
    }

    /*-----------------------------------------------------------------*/
    /* Skip all bad blocks following current block.                    */
    /*-----------------------------------------------------------------*/
    for (++i; i < Flash->num_blocks && Flash->blocks[i].bad_block; ++i) ;

    /*-----------------------------------------------------------------*/
    /* If end of contiguous segment, account for it.                   */
    /*-----------------------------------------------------------------*/
    if (i != next_sect / Flash->block_sects)
      ctrl_num_shorts += 2;
  }

  /*-------------------------------------------------------------------*/
  /* Now count the space for the used sectors (per file).              */
  /*-------------------------------------------------------------------*/
  for (sector = 0; sector < Flash->num_sects;)
  {
    /*-----------------------------------------------------------------*/
    /* If sector is beginning of file, count whole file sector list.   */
    /*-----------------------------------------------------------------*/
    if (Flash->sect_tbl[sector].prev == FLAST_SECT && used_sect(sector))
    {
      /*---------------------------------------------------------------*/
      /* Count head of list.                                           */
      /*---------------------------------------------------------------*/
      ctrl_num_shorts += 1;

      /*---------------------------------------------------------------*/
      /* Walk the list a contiguous segment at a time.                 */
      /*---------------------------------------------------------------*/
      for (curr_sect = sector; curr_sect != FLAST_SECT;)
      {
        /*-------------------------------------------------------------*/
        /* Count current contiguous segment. For NOR skip headers.     */
        /*-------------------------------------------------------------*/
        if (Flash->type == FFS_NOR)
          for (last_in_segment = curr_sect;; last_in_segment = next_sect)
          {
            next_sect = last_in_segment + 1;
            if (next_sect < Flash->num_sects &&
                Flash->sect_tbl[next_sect].prev == FHDER_SECT)
              next_sect += Flash->hdr_sects;
            if (Flash->sect_tbl[last_in_segment].next != next_sect)
              break;
          }
        else
          for (last_in_segment = curr_sect;
            Flash->sect_tbl[last_in_segment].next == last_in_segment + 1;
            ++last_in_segment) ;

        /*-------------------------------------------------------------*/
        /* If more than 1 sect in segment, count label and last sect.  */
        /*-------------------------------------------------------------*/
        if (curr_sect != last_in_segment)
          ctrl_num_shorts += 2;

        /*-------------------------------------------------------------*/
        /* Count next pointer.                                         */
        /*-------------------------------------------------------------*/
        ctrl_num_shorts += 1;

        /*-------------------------------------------------------------*/
        /* Increment sector counter if first segment in file list.     */
        /*-------------------------------------------------------------*/
        if (curr_sect == sector)
          sector = last_in_segment + 1;

        /*-------------------------------------------------------------*/
        /* Move to new segment.                                        */
        /*-------------------------------------------------------------*/
        curr_sect = Flash->sect_tbl[last_in_segment].next;
      }
    }

    /*-----------------------------------------------------------------*/
    /* Else move to next sector to look at.                            */
    /*-----------------------------------------------------------------*/
    else
      ++sector;
  }

  /*-------------------------------------------------------------------*/
  /* Account for the last FLAST_SECT marking for end of table.         */
  /*-------------------------------------------------------------------*/
  ctrl_num_shorts += 1;

  /*-------------------------------------------------------------------*/
  /* Add space for the files tables.                                   */
  /*-------------------------------------------------------------------*/
  table_size = Flash->tbls_size + Flash->total * sizeof(ui8);

  /*-------------------------------------------------------------------*/
  /* The ctrl size consists of the size of the files tables + the fixed*/
  /* number of ui32s + size of sectors table (in shorts) + wear count  */
  /* offsets for every block (2 offsets -> byte) + CRC and bad blocks  */
  /* (NAND only) or fast mount byte (NOR only) or CRC(MLC only).       */
  /*-------------------------------------------------------------------*/
  ctrl_num_shorts += 10;
  ctrl_size = table_size + FLASH_CTRL_UI32s * sizeof(ui32) +
              sizeof(ui16) * ctrl_num_shorts + (Flash->num_blocks + 1) /
              2 * sizeof(ui8);
  if (Flash->type == FFS_NAND)
    ctrl_size += (Flash->num_blocks + 7) / 8 + 4;
  else
    ctrl_size += 1;

#if QUOTA_ENABLED
  /*-------------------------------------------------------------------*/
  /* Count the quota enabled flag.                                     */
  /*-------------------------------------------------------------------*/
  ctrl_size += 1;
#endif /* QUOTA_ENABLED */

  /*-------------------------------------------------------------------*/
  /* Add the size taken by writing the ctrl blocks.                    */
  /*-------------------------------------------------------------------*/
  ctrl_size += sizeof(ui16);
  ctrl_sects = (ctrl_size + Flash->sect_sz - 1) / Flash->sect_sz;
  free_ctrl_sects = (ui32)((Flash->free_ctrl_sect == (ui32)-1) ? 0 :
                           (Flash->block_sects -
                            Flash->free_ctrl_sect % Flash->block_sects));
  if (ctrl_sects > free_ctrl_sects)
  {
    incr = (ctrl_sects - free_ctrl_sects + Flash->block_sects - 1)
           / Flash->block_sects + 1;
    ctrl_size += 8 * incr;
    ctrl_num_shorts += 4 * incr;
  }

  /*-------------------------------------------------------------------*/
  /* Save update control information byte size and sector count.       */
  /*-------------------------------------------------------------------*/
  Flash->ctrl_size = ctrl_size;
  Flash->ctrl_sects = (Flash->ctrl_size + Flash->sect_sz - 1) /
                       Flash->sect_sz;

  /*-------------------------------------------------------------------*/
  /* Readjust the erase set size based on new ctrl info size.          */
  /*-------------------------------------------------------------------*/
  adjust_set_size(adjust_erase, check_recycle);

  /*-------------------------------------------------------------------*/
  /* Return the number of ui16's it takes to write sect_tbl.           */
  /*-------------------------------------------------------------------*/
  return ctrl_num_shorts;
}

/***********************************************************************/
/*  free_block: Attempt to free block and add it to free list          */
/*                                                                     */
/*      Inputs: block = block to be erased                             */
/*              last_dirty = last dirty sector in corrupt free list    */
/*              adjust_set = flag to indicate if erase set has changed */
/*              modified = flag to sync if state changes               */
/*                                                                     */

⌨️ 快捷键说明

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