📄 fsinit.c
字号:
/***********************************************************************/
/* */
/* 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 + -