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

📄 rsinit.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************/
/*                                                                     */
/*   Module:  rsinit.c                                                 */
/*   Release: 2004.5                                                   */
/*   Version: 2003.0                                                   */
/*   Purpose: Initialization functions for RAM file system             */
/*                                                                     */
/*---------------------------------------------------------------------*/
/*                                                                     */
/*               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 "ramfsp.h"

#if NUM_RFS_VOLS

/***********************************************************************/
/* Global Variable Declarations                                        */
/***********************************************************************/
SEM      RamSem;
RamGlob *Ram;
RamGlob  RamGlobals[NUM_RFS_VOLS];

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

/***********************************************************************/
/*  free_files: Clear memory associated with files in a table          */
/*                                                                     */
/*       Input: table = pointer to files table                         */
/*                                                                     */
/***********************************************************************/
static void free_files(const RFSEnts *table)
{
  int i;
  RamSect *curr_sect, *next_sect;

  /*-------------------------------------------------------------------*/
  /* For each file, free its sector list.                              */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < FNUM_ENT; ++i)
    if (table->tbl[i].type == FCOMMN)
    {
      for (curr_sect = (RamSect *)table->tbl[i].entry.comm.frst_sect;
           curr_sect;)
      {
        next_sect = curr_sect->next;
        free(curr_sect);
        curr_sect = next_sect;
      }
    }
}

/***********************************************************************/
/* Global Function Definitions                                         */
/***********************************************************************/

/***********************************************************************/
/* GetRamTable: Allocate new RAM file system table                     */
/*                                                                     */
/*     Returns: pointer to allocated table or NULL on error            */
/*                                                                     */
/***********************************************************************/
RFSEnts *GetRamTable(void)
{
  RFSEnts *r_value = malloc(sizeof(RFSEnts));
  int i;

  /*-------------------------------------------------------------------*/
  /* If malloc() succeeded, allocate new table.                        */
  /*-------------------------------------------------------------------*/
  if (r_value)
  {
    r_value->next_tbl = NULL;
    r_value->free = FNUM_ENT - 1;

    /*-----------------------------------------------------------------*/
    /* Empty out all the table.                                        */
    /*-----------------------------------------------------------------*/
    for (i = 0; i < FNUM_ENT; ++i)
      r_value->tbl[i].type = FEMPTY;
  }
  else
    set_errno(ENOSPC);

  return r_value;
}

/***********************************************************************/
/*   RfsModule: RAM file system interface to software object manager   */
/*                                                                     */
/*       Input: req = module request code                              */
/*              ... = additional parameters specific to request        */
/*                                                                     */
/***********************************************************************/
void *RfsModule(int req, ...)
{
  void *r_value = NULL;
  va_list ap;
  char *device;
  int i, v;
  RamGlob *vol;

  switch (req)
  {
    case kInitMod:
    {
      /*---------------------------------------------------------------*/
      /* Allocate the synchronization mechanism data structures.       */
      /*---------------------------------------------------------------*/
      RamSem = semCreate("RAM_SEM", 1, OS_FIFO);
      if (RamSem == NULL)
        r_value = (void *)-1;

      /*---------------------------------------------------------------*/
      /* Mark all potential volume holders as empty.                   */
      /*---------------------------------------------------------------*/
      for (i = 0; i < NUM_RFS_VOLS; ++i)
        RamGlobals[i].num_sects = (ui32)-1;
      break;
    }

    case kFormat:
    {
      RFSEnts *temp_table, *prev_table;
      RFSEnt *curr_dir;
      ui32 dummy;

      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to fetch the device name.            */
      /*---------------------------------------------------------------*/
      va_start(ap, req);
      device = va_arg(ap, char *);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Go through all the existing volumes (mounted and not mounted) */
      /* and if any has the given name, format it.                     */
      /*---------------------------------------------------------------*/
      for (v = 0; v < NUM_RFS_VOLS; ++v)
      {
        vol = &RamGlobals[v];

        /*-------------------------------------------------------------*/
        /* If this entry contains a valid volume and the names match,  */
        /* format the volume.                                          */
        /*-------------------------------------------------------------*/
        if (vol->num_sects != (ui32)-1 && !strcmp(device, vol->sys.name))
        {
          /*-----------------------------------------------------------*/
          /* Acquire exclusive access to RAM.                          */
          /*-----------------------------------------------------------*/
          semPend(RamSem, WAIT_FOREVER);

          /*-----------------------------------------------------------*/
          /* If there are more than one FileTables, delete the rest.   */
          /*-----------------------------------------------------------*/
          FsReadCWD(&dummy, (void *)&curr_dir);
          for (temp_table = vol->files_tbl->next_tbl; temp_table;)
          {
            /*---------------------------------------------------------*/
            /* If the current directory is in this table set it to     */
            /* first entry for this volume, the root directory.        */
            /*---------------------------------------------------------*/
            if (curr_dir >= &temp_table->tbl[0] &&
                curr_dir <= &temp_table->tbl[FNUM_ENT])
            {
              ++vol->files_tbl->tbl[0].entry.dir.cwds;
              FsSaveCWD(dummy, (ui32)&vol->files_tbl->tbl[0]);
            }

            /*---------------------------------------------------------*/
            /* Free all sectors from all files in this table.          */
            /*---------------------------------------------------------*/
            free_files(temp_table);

            /*---------------------------------------------------------*/
            /* Free table.                                             */
            /*---------------------------------------------------------*/
            prev_table = temp_table;
            temp_table = temp_table->next_tbl;
            free(prev_table);
          }
          vol->files_tbl->next_tbl = NULL;

          /*-----------------------------------------------------------*/
          /* Set all FileTable entries to empty, except for first two. */
          /*-----------------------------------------------------------*/
          free_files(vol->files_tbl);
          for (i = 2; i < FNUM_ENT; ++i)
          {
            vol->files_tbl->tbl[i].type = FEMPTY;

            /*---------------------------------------------------------*/
            /* If the current directory is this entry, set it to first */
            /* entry in the table, the root directory.                 */
            /*---------------------------------------------------------*/
            if (curr_dir == &vol->files_tbl->tbl[i])
            {
              ++vol->files_tbl->tbl[0].entry.dir.cwds;
              FsSaveCWD(dummy, (ui32)&vol->files_tbl->tbl[0]);
            }
          }
          vol->total_free = FNUM_ENT - 2;

          /*-----------------------------------------------------------*/
          /* Set the root dir's first entry to NULL.                   */
          /*-----------------------------------------------------------*/
          vol->files_tbl->tbl[0].entry.dir.first = NULL;

          /*-----------------------------------------------------------*/
          /* Release exclusive access to RAM.                          */
          /*-----------------------------------------------------------*/
          semPost(RamSem);

          /*-----------------------------------------------------------*/
          /* If volume is not mounted, just return success.            */
          /*-----------------------------------------------------------*/
          if ((vol->sys.next == NULL) && (vol->sys.prev == NULL) &&
              (&vol->sys != MountedList.head))
            return (void *)1;

          /*-----------------------------------------------------------*/
          /* Make sure no FILE* or DIR* is associated with the system. */
          /*-----------------------------------------------------------*/
          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;
            }
          }
          r_value = (void *)1;
        }
      }
      break;
    }

    case kVolName:
    {
      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to fetch the name to look for.       */
      /*---------------------------------------------------------------*/
      va_start(ap, req);
      device = va_arg(ap, char *);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Look for name duplication.                                    */
      /*---------------------------------------------------------------*/
      for (i = 0; i < NUM_RFS_VOLS; ++i)
        if (RamGlobals[i].num_sects != (ui32)-1 &&
            !strcmp(device, RamGlobals[i].sys.name))
        {
          set_errno(EEXIST);
          r_value = (void *)-1;
          break;
        }
      break;
    }

    case kMount:
    {
      char **device_name;

      /*---------------------------------------------------------------*/
      /* Use the va_arg mechanism to fetch the device name.            */
      /*---------------------------------------------------------------*/
      va_start(ap, req);
      device = va_arg(ap, char *);
      device_name = va_arg(ap, char **);
      va_end(ap);

      /*---------------------------------------------------------------*/
      /* Look for the device name among the RAM volumes.               */
      /*---------------------------------------------------------------*/
      for (v = 0; v < NUM_RFS_VOLS; ++v)
      {
        Ram = &RamGlobals[v];

        /*-------------------------------------------------------------*/
        /* If matching entry found, mount it.                          */
        /*-------------------------------------------------------------*/
        if (Ram->num_sects != (ui32)-1 &&
            ((device == NULL || !strcmp(device, Ram->sys.name)) &&
             Ram->sys.prev == NULL && Ram->sys.next == NULL &&
             &Ram->sys != MountedList.head))
        {
          *device_name = Ram->sys.name;
          r_value = &Ram->sys;
          break;
        }
      }
      break;
    }

    default:
      break;
  }
  return r_value;
}

/***********************************************************************/
/*  RamNewSect: Allocate space for new sector and add it to file       */
/*                                                                     */
/*       Input: entry = file entry                                     */
/*                                                                     */
/*     Returns: 0 on success, -1 on failure                            */
/*                                                                     */
/***********************************************************************/
int RamNewSect(RCOM_T *entry)
{
  RamSect *new_sect;
  int i;

  /*-------------------------------------------------------------------*/

⌨️ 快捷键说明

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