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

📄 fsintrnl.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************/
/*                                                                     */
/*   Module:  fsintrnl.c                                               */
/*   Release: 2004.5                                                   */
/*   Version: 2004.15                                                  */
/*   Purpose: Implements the internal functions for the flash files    */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*               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 "flashfsp.h"

#if NUM_FFS_VOLS

#define TIMING FALSE
#if TIMING
#include "../../../include/libc/time.h"
clock_t TotWrCtrl = 0, PreWrCtrl = 0, TotRec = 0, RecWrCtrl = 0;
ui32 RecCount = 0, WrCtrlCount = 0;
#endif

#define DO_JMP_RECYCLE     FALSE
#if DO_JMP_RECYCLE
extern int EnableCount;
#endif

/***********************************************************************/
/* Symbol Definitions                                                  */
/***********************************************************************/
#define SINGLE_USED        1  /* Flags for sector values on flash */
#define MULTIPLE_USED      2
#define SINGLE_FREE        3
#define MULTIPLE_FREE      4
#define SINGLE_DIRTY       5
#define MULTIPLE_DIRTY     6
#define BLOCK_INVALID      7

#define MAX_WDELTA         15 /* Maximum allowed wear count diff */

#define FLASH_CTRL_UI32s   13 /* Num of ui32s present in ctrl info */

#define WRITE_CTRL         TRUE
#define SKIP_WRITE_CTRL    FALSE

#define SKIP_SECTS         TRUE
#define DONT_SKIP_SECTS    FALSE

#define FFS_FAILED_POWER_UP    1
#define FFS_NORMAL_POWER_UP    2
#define FFS_SLOW_POWER_UP      3

/***********************************************************************/
/* Macro Definitions                                                   */
/***********************************************************************/
#if FFS_SWAP_ENDIAN
  #define write_ctrl_ui32(v)                                            \
    v_ui32 = v;                                                         \
    v_ui32 = ((v_ui32 & 0xFF) << 24) | ((v_ui32 & 0xFF00) << 8) |       \
             ((v_ui32 & 0xFF0000) >> 8) | ((v_ui32 & 0xFF000000) >> 24);\
    status = Flash->write_ctrl(&v_ui32, sizeof(ui32));                  \
    if (status)                                                         \
      goto WrCtrl_exit;

  #define write_ctrl_ui16(v)                                            \
    v_ui16 = v;                                                         \
    v_ui16 = (ui16)(((v_ui16 & 0xFF) << 8) | ((v_ui16 & 0xFF00) >> 8)); \
    status  = Flash->write_ctrl(&v_ui16, sizeof(ui16))                  \
    if (status)                                                         \
      goto WrCtrl_exit;
#else
  #define write_ctrl_ui32(v)                           \
    v_ui32 = v;                                        \
    status = Flash->write_ctrl(&v_ui32, sizeof(ui32)); \
    if (status)                                        \
      goto WrCtrl_exit;

  #define write_ctrl_ui16(v)                           \
    v_ui16 = v;                                        \
    status = Flash->write_ctrl(&v_ui16, sizeof(ui16)); \
    if (status)                                        \
      goto WrCtrl_exit;
#endif /* FFS_SWAP_ENDIAN */

#if FFS_DEBUG
int printf(const char *, ...);
#endif

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

/***********************************************************************/
/*   read_ctrl: Read a chunk of control memory from flash              */
/*                                                                     */
/*      Inputs: head = address to write to in RAM                      */
/*              length = number of bytes the chunk has                 */
/*                                                                     */
/*     Returns: 0 on success, -1 on error                              */
/*                                                                     */
/***********************************************************************/
static int read_ctrl(void *head, uint length)
{
  static ui32 offset = 0;
  ui8 *dst = head;
  ui16 next_ctrl_block = 0xFFFF;

  /*-------------------------------------------------------------------*/
  /* If length is zero, reset offset and read first sector.            */
  /*-------------------------------------------------------------------*/
  if (length == 0)
  {
    offset = 0;
    if (Flash->read_sector(Flash->tmp_sect, Flash->ctrl_sect))
    {
      set_errno(EIO);
      return -1;
    }
    return 0;
  }

  /*-------------------------------------------------------------------*/
  /* Loop, reading one byte at a time.                                 */
  /*-------------------------------------------------------------------*/
  do
  {
    /*-----------------------------------------------------------------*/
    /* If needed, read new sector from flash.                          */
    /*-----------------------------------------------------------------*/
    if (offset == Flash->sect_sz)
    {
      /*---------------------------------------------------------------*/
      /* If at block boundary, update using NextCtrlBlock.             */
      /*---------------------------------------------------------------*/
      if ((++Flash->ctrl_sect % Flash->block_sects) == 0)
      {
        PfAssert(next_ctrl_block < Flash->num_blocks);
        Flash->ctrl_sect = next_ctrl_block * Flash->block_sects +
                           Flash->hdr_sects;
      }

      /*---------------------------------------------------------------*/
      /* Read whole sector in and reset the sector offset.             */
      /*---------------------------------------------------------------*/
      if (Flash->read_sector(Flash->tmp_sect, Flash->ctrl_sect))
      {
        set_errno(EIO);
        return -1;
      }
      offset = 0;
    }

    /*-----------------------------------------------------------------*/
    /* If this is last sector in block, and we are down to last two    */
    /* bytes, read in next ctrl block.                                 */
    /*-----------------------------------------------------------------*/
    if (offset == Flash->sect_sz - 2 &&
        (Flash->ctrl_sect + 1) % Flash->block_sects == 0)
    {
      next_ctrl_block  = (ui16)(Flash->tmp_sect[offset++] << 8);
      next_ctrl_block |= Flash->tmp_sect[offset++];
    }
    else
    {
      /*---------------------------------------------------------------*/
      /* Read one byte of control information and increment.           */
      /*---------------------------------------------------------------*/
      *dst++ = Flash->tmp_sect[offset++];
      --length;
    }
  }
  while (length);
  return 0;
}

/***********************************************************************/
/* read_ctrl_ui32: Read a ui32 from flash in big endian and convert to */
/*              machine endianess                                      */
/*                                                                     */
/*       Input: val = place to store the read ui32                     */
/*                                                                     */
/*     Returns: 0 on success, -1 on failure                            */
/*                                                                     */
/***********************************************************************/
static int read_ctrl_ui32(ui32 *val)
{
#if FFS_SWAP_ENDIAN
  ui32 tmp;
#endif

  if (read_ctrl(val, sizeof(ui32)))
    return -1;

#if FFS_SWAP_ENDIAN
  tmp = *val;
  *val = ((tmp & 0xFF) << 24) | ((tmp & 0xFF00) << 8) |
         ((tmp & 0xFF0000) >> 8) | ((tmp & 0xFF000000) >> 24);
#endif
  return 0;
}

/***********************************************************************/
/* read_ctrl_ui16: Read a ui16 from flash in big endian and convert to */
/*              machine endianess                                      */
/*                                                                     */
/*       Input: val = place to store the read ui16                     */
/*                                                                     */
/*     Returns: 0 on success, -1 on failure                            */
/*                                                                     */
/***********************************************************************/
static int read_ctrl_ui16(ui16 *val)
{
#if FFS_SWAP_ENDIAN
  ui16 tmp;
#endif

  if (read_ctrl(val, sizeof(ui16)))
    return -1;

#if FFS_SWAP_ENDIAN
  tmp = *val;
  *val = (ui16)(((tmp & 0xFF) << 8) | ((tmp & 0xFF00) >> 8));
#endif
  return 0;
}

/***********************************************************************/
/* readjust_set: Fill -1 slots in erase set with blocks                */
/*                                                                     */
/***********************************************************************/
static void readjust_set(void)
{
  ui32 i, j, sect;
  int  b, max_f, f_b, max_b;
  ui32 free_blck, last_in_free_block;

  /*-------------------------------------------------------------------*/
  /* First, shift all non -1 slots to the front.                       */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < Flash->set_blocks; ++i)
    if (Flash->erase_set[i] == -1)
    {
      for (j = i + 1; j < Flash->set_blocks; ++j)
        if (Flash->erase_set[j] != -1)
          break;
      if (j >= Flash->set_blocks)
        break;
      Flash->erase_set[i] = Flash->erase_set[j];
      Flash->erase_set[j] = -1;
    }
  for (j = 0; j < i; ++j)
    Flash->blocks[Flash->erase_set[j]].bad_block = TRUE;

  /*-------------------------------------------------------------------*/
  /* Now fill all -1 slots with new blocks.                            */
  /*-------------------------------------------------------------------*/
  for (; i < Flash->set_blocks; ++i)
  {
    for (b = 0, max_f = -1; b < Flash->num_blocks; ++b)
    {
      /*---------------------------------------------------------------*/
      /* If block is not bad, ctrl and has no free sects, candidate.   */
      /*---------------------------------------------------------------*/
      if (!Flash->blocks[b].bad_block && !Flash->blocks[b].ctrl_block &&
          Flash->sect_tbl[(b + 1) * Flash->block_sects - 1].prev !=
          FFREE_SECT)
      {
        /*-------------------------------------------------------------*/
        /* Sanity check.                                               */
        /*-------------------------------------------------------------*/
        PfAssert(Flash->high_wear >= Flash->blocks[b].wear_count);

        /*-------------------------------------------------------------*/
        /* Compute the selector.                                       */
        /*-------------------------------------------------------------*/
        f_b = (int)(16 * (Flash->block_sects -
                    Flash->blocks[b].used_sects) +

⌨️ 快捷键说明

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