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

📄 fsinit.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************/
/*                                                                     */
/*   Module:  fsinit.c                                                 */
/*   Release: 2004.5                                                   */
/*   Version: 2004.8                                                   */
/*   Purpose: Implements the initialization functions for the flash    */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*               Copyright 2004, Blunk Microsystems                    */
/*                      ALL RIGHTS RESERVED                            */
/*                                                                     */
/*   Licensees have the non-exclusive right to use, modify, or extract */
/*   this computer program for software development at a single site.  */
/*   This program may be resold or disseminated in executable format   */
/*   only. The source code may not be redistributed or resold.         */
/*                                                                     */
/***********************************************************************/
#include <stdarg.h>
#include "flashfsp.h"

#if NUM_FFS_VOLS

/***********************************************************************/
/* Symbol Defintions                                                   */
/***********************************************************************/
#define FFS_MAX_SIZE   0xFFFB

/***********************************************************************/
/* Global Variable Declarations                                        */
/***********************************************************************/
FlashGlob  FlashGlobals[NUM_FFS_VOLS];
SEM        FlashSem;
FlashGlob *Flash;

/***********************************************************************/
/* Local Function Definitions                                          */
/***********************************************************************/

/***********************************************************************/
/* assign_volume_mem: Allocate memory for internal structures          */
/*                                                                     */
/*     Returns: 0 on success, -1 on error                              */
/*                                                                     */
/***********************************************************************/
static int assign_volume_mem(void)
{
  int sect_sz;

  /*-------------------------------------------------------------------*/
  /* Allocate memory for the sectors table.                            */
  /*-------------------------------------------------------------------*/
  Flash->sect_tbl = malloc(sizeof(Sectors) * Flash->num_sects);
  if (Flash->sect_tbl == NULL)
  {
    set_errno(ENOSPC);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Allocate memory for the used counters table.                      */
  /*-------------------------------------------------------------------*/
  Flash->blocks = malloc(sizeof(FFSBlock) * Flash->num_blocks);
  if (Flash->blocks == NULL)
  {
    set_errno(ENOSPC);
    free(Flash->sect_tbl);
    Flash->sect_tbl = NULL;
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Allocate memory for the set table.                                */
  /*-------------------------------------------------------------------*/
  Flash->erase_set = malloc(sizeof(int) * Flash->max_set_blocks);
  if (Flash->erase_set == NULL)
  {
    free(Flash->sect_tbl);
    Flash->sect_tbl = NULL;
    free(Flash->blocks);
    Flash->blocks = NULL;
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Set the cache.                                                    */
  /*-------------------------------------------------------------------*/
  sect_sz = Flash->sect_sz;
  PfAssert(sect_sz % 2 == 0);
  if (!InitCache(&Flash->cache, FOPEN_MAX, FlashWrprWr,
                 Flash->read_sector, sect_sz, 1, CACHE_UI32_ALLIGN))
  {
    free(Flash->sect_tbl);
    Flash->sect_tbl = NULL;
    free(Flash->blocks);
    Flash->blocks = NULL;
    free(Flash->erase_set);
    Flash->erase_set = NULL;
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Assign pointer to extra sector in cache for use by the internals  */
  /* of the file system.                                               */
  /*-------------------------------------------------------------------*/
  Flash->tmp_sect = (ui8 *)(Flash->cache.pool[FOPEN_MAX - 1].sector +
                            Flash->sect_sz);

  return 0;
}

/***********************************************************************/
/* init_volume: Prepare unformatted volume for format                  */
/*                                                                     */
/*     Returns: 0 on success, -1 on error                              */
/*                                                                     */
/***********************************************************************/
static int init_volume(void)
{
  int i;
  FFSEnt *v_ent;

  /*-------------------------------------------------------------------*/
  /* Assign volume memory.                                             */
  /*-------------------------------------------------------------------*/
  if (assign_volume_mem())
    return -1;

  /*-------------------------------------------------------------------*/
  /* Set ctrl info pointer to invalid and the seq num to 0.            */
  /*-------------------------------------------------------------------*/
  Flash->frst_ctrl_sect = Flash->last_ctrl_sect = (ui32)-1;
  Flash->seq_num = 0;

  /*-------------------------------------------------------------------*/
  /* Set the file number generator.                                    */
  /*-------------------------------------------------------------------*/
  Flash->fileno_gen = 1;

  /*-------------------------------------------------------------------*/
  /* Set the high wear count.                                          */
  /*-------------------------------------------------------------------*/
  Flash->high_wear = 0;

  /*-------------------------------------------------------------------*/
  /* Allocate the first table, the files table.                        */
  /*-------------------------------------------------------------------*/
  Flash->files_tbl = FlashGetTbl();
  if (!Flash->files_tbl)
  {
    free(Flash->sect_tbl);
    Flash->sect_tbl = NULL;
    free(Flash->blocks);
    Flash->blocks = NULL;
    free(Flash->erase_set);
    Flash->erase_set = NULL;
    DestroyCache(&Flash->cache);
    return -1;
  }
  Flash->files_tbl->free = FNUM_ENT - 2;

  /*-------------------------------------------------------------------*/
  /* Set all entries in files table to empty except for the first two. */
  /*-------------------------------------------------------------------*/
  for (i = 2; i < FNUM_ENT; ++i)
    Flash->files_tbl->tbl[i].type = FEMPTY;

  /*-------------------------------------------------------------------*/
  /* Get pointer to the second entry in the files table.               */
  /*-------------------------------------------------------------------*/
  v_ent = &Flash->files_tbl->tbl[1];

  /*-------------------------------------------------------------------*/
  /* Set second entry in files table to be the file struct associated  */
  /* with the root directory.                                          */
  /*-------------------------------------------------------------------*/
  v_ent->type = FCOMMN;
  v_ent->entry.comm.open_mode = 0;
  v_ent->entry.comm.links = 1;
  v_ent->entry.comm.open_links = 0;
  v_ent->entry.comm.attrib = 0;
  v_ent->entry.comm.fileno = 0;
  v_ent->entry.comm.frst_sect = (ui16)-1;
  v_ent->entry.comm.last_sect = (ui16)-1;
  v_ent->entry.comm.mod_time = v_ent->entry.comm.ac_time = OsSecCount;
  v_ent->entry.comm.one_past_last.offset = 0;
  v_ent->entry.comm.one_past_last.sector = (ui16)-1;
  v_ent->entry.comm.addr = v_ent;
  v_ent->entry.comm.size = 0;

  /*-------------------------------------------------------------------*/
  /* Get pointer to the first entry in the files table.                */
  /*-------------------------------------------------------------------*/
  v_ent = &Flash->files_tbl->tbl[0];

  /*-------------------------------------------------------------------*/
  /* Set the first entry in files table to be root dir.                */
  /*-------------------------------------------------------------------*/
  v_ent->type = FDIREN;
  v_ent->entry.dir.cwds = 0;
  v_ent->entry.dir.next = NULL;
  v_ent->entry.dir.prev = NULL;
  v_ent->entry.dir.comm = &(Flash->files_tbl->tbl[1].entry.comm);
  v_ent->entry.dir.parent_dir = NULL;
  v_ent->entry.dir.first = NULL;
  strcpy(v_ent->entry.dir.name, Flash->sys.name);

  /*-------------------------------------------------------------------*/
  /* Set the permissions for the root directory.                       */
  /*-------------------------------------------------------------------*/
  SetPerm(v_ent->entry.dir.comm, S_IROTH | S_IWOTH | S_IXOTH);

  /*-------------------------------------------------------------------*/
  /* Set the other variables for this volume.                          */
  /*-------------------------------------------------------------------*/
  Flash->total_free = FNUM_ENT - 2;
  Flash->total = FNUM_ENT;
  Flash->ctrl_size = Flash->ctrl_sects = 0;

  /*-------------------------------------------------------------------*/
  /* Update file tables size.                                          */
  /*-------------------------------------------------------------------*/
  Flash->tbls_size = (OFDIR_SZ + OFCOM_SZ + 1 +
                      strlen(Flash->files_tbl->tbl[0].entry.dir.name));

#if QUOTA_ENABLED
  /*-------------------------------------------------------------------*/
  /* Set the quotas value for the root directory if quota enabled.     */
  /*-------------------------------------------------------------------*/
  if (Flash->quota_enabled)
  {
    /*-----------------------------------------------------------------*/
    /* max_q is set based on the type of file system. The value is     */
    /* based on the total number of sectors minus the space that has   */
    /* to be free for recycles and worst encoding of sector table.     */
    /*-----------------------------------------------------------------*/
    if (Flash->type == FFS_NAND)
      v_ent->entry.dir.max_q = Flash->num_sects -
        Flash->block_sects * (Flash->max_bad_blocks + 2 +
                              (Flash->max_set_blocks + 1) / 2) -
        ((2 * (1 + CONSEC_DISTURBS) * (Flash->num_sects -
          (Flash->max_bad_blocks + 2) * Flash->block_sects) +
          Flash->sect_sz - 1) / Flash->sect_sz);
    else
      v_ent->entry.dir.max_q = Flash->num_sects -
        Flash->block_sects * (2 + (Flash->max_set_blocks + 1) / 2) -
        ((2 * (Flash->num_sects - 2 * Flash->block_sects) +
         Flash->sect_sz - 1) / Flash->sect_sz);
    v_ent->entry.dir.max_q -= EXTRA_FREE / Flash->sect_sz;
    v_ent->entry.dir.max_q *= Flash->sect_sz;

    /*-----------------------------------------------------------------*/
    /* Set the rest of the quota values.                               */
    /*-----------------------------------------------------------------*/
    v_ent->entry.dir.min_q = 0;
    v_ent->entry.dir.free_below = 0;
    v_ent->entry.dir.res_below = 0;
    v_ent->entry.dir.used = strlen(v_ent->entry.dir.name) + 1 + OFDIR_SZ
                          + OFDIR_QUOTA_SZ + OFCOM_SZ;
    v_ent->entry.dir.free = v_ent->entry.dir.max_q -
                            v_ent->entry.dir.used;
    Flash->tbls_size += OFDIR_QUOTA_SZ;
  }
#endif /* QUOTA_ENABLED */

  return 0;
}

/***********************************************************************/
/* prepare_mounted_for_format: Prepare a mounted volume for format     */
/*                                                                     */
/*       Input: vol = pointer to flash volume                          */
/*                                                                     */
/*     Returns: 0 on success, 1 on error                               */
/*                                                                     */
/***********************************************************************/
static int prepare_mounted_for_format(FlashGlob *vol)
{
  FFSEnts *temp_tbl, *prev_tbl;
  ui32     i, sect, block, dummy;
  FFSEnt *curr_dir;
  int sect_sz;

  /*-------------------------------------------------------------------*/
  /* Step through all files, invalidating those associated with volume.*/
  /*-------------------------------------------------------------------*/
  for (i = 0; i < FOPEN_MAX; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* If a FILE is associated with this volume, clear it.             */
    /*-----------------------------------------------------------------*/
    if (Files[i].volume == vol)
    {
      Files[i].ioctl = NULL;
      Files[i].volume = NULL;
      Files[i].handle = Files[i].cached = NULL;
    }
  }

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive access to volume and flash file system.         */

⌨️ 快捷键说明

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