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

📄 rsinit.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Assign space for new sector.                                      */
  /*-------------------------------------------------------------------*/
  new_sect = malloc(sizeof(RamSect));
  if (new_sect == NULL)
    return -1;

  /*-------------------------------------------------------------------*/
  /* Append new sector to end of sector list.                          */
  /*-------------------------------------------------------------------*/
  if (entry->frst_sect == NULL)
  {
    entry->frst_sect = new_sect;

    /*-----------------------------------------------------------------*/
    /* In case it is the first sector, update current FCB pointer for  */
    /* all the ones pointing to this file.                             */
    /*-----------------------------------------------------------------*/
    for (i = 0; i < FOPEN_MAX; ++i)
      if (Files[i].ioctl == RamIoctl && Files[i].volume == Ram &&
          ((RFIL_T *)Files[i].handle)->comm == entry)
      {
        PfAssert(Files[i].curr_ptr.sector == (ui32)NULL ||
                 Files[i].curr_ptr.sector == SEEK_PAST_END);
        Files[i].curr_ptr.sector = (ui32)new_sect;
        Files[i].curr_ptr.offset = 0;
        Files[i].curr_ptr.sect_off = 0;
        Files[i].old_ptr = Files[i].curr_ptr;
      }
  }
  else
    ((RamSect *)entry->last_sect)->next = new_sect;
  new_sect->next = NULL;
  new_sect->prev = (RamSect *)entry->last_sect;
  entry->last_sect = new_sect;
  entry->one_past_last = 0;

  ++Ram->num_sects;

  return 0;
}

/***********************************************************************/
/* RamFreeSect: Remove last sector from a file's sector list           */
/*                                                                     */
/*       Input: entry = file entry                                     */
/*                                                                     */
/***********************************************************************/
void RamFreeSect(RCOM_T *entry)
{
  RamSect *new_last_sect;

  /*-------------------------------------------------------------------*/
  /* Remove last sector from sector list.                              */
  /*-------------------------------------------------------------------*/
  entry->size -= entry->one_past_last;
  new_last_sect = ((RamSect *)entry->last_sect)->prev;
  if (new_last_sect == NULL)
  {
    entry->frst_sect = NULL;
    PfAssert(entry->size == 0);
  }
  else
  {
    new_last_sect->next = NULL;
    entry->one_past_last = RAM_SECT_SZ;
  }
  free(entry->last_sect);
  entry->last_sect = new_last_sect;

  --Ram->num_sects;
}

/***********************************************************************/
/*   RfsDelVol: Remove volume from list of RAM volumes and free up its */
/*              resources                                              */
/*                                                                     */
/*       Input: name = name of volume to be deleted                    */
/*                                                                     */
/*     Returns: 0 on success, -1 on error                              */
/*                                                                     */
/***********************************************************************/
int RfsDelVol(const char *name)
{
  int i;
  RFSEnts *curr_tbl, *next_tbl;

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive acess to the RAM file system.                   */
  /*-------------------------------------------------------------------*/
  semPend(RamSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* Look for volume in the RamGlobals array.                          */
  /*-------------------------------------------------------------------*/
  for (i = 0;; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* If the volume was not found, return error.                      */
    /*-----------------------------------------------------------------*/
    if (i == NUM_RFS_VOLS)
    {
      set_errno(ENOENT);
      semPost(RamSem);
      return -1;
    }

    /*-----------------------------------------------------------------*/
    /* Break if match is found.                                        */
    /*-----------------------------------------------------------------*/
    if (RamGlobals[i].num_sects != (ui32)-1 &&
        !strcmp(name, RamGlobals[i].sys.name))
      break;
  }

  /*-------------------------------------------------------------------*/
  /* If volume is mounted, return error.                               */
  /*-------------------------------------------------------------------*/
  if (RamGlobals[i].sys.next != NULL ||
      RamGlobals[i].sys.prev != NULL ||
      &RamGlobals[i].sys == MountedList.head)
  {
    set_errno(EBUSY);
    semPost(RamSem);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Free up volume resources.                                         */
  /*-------------------------------------------------------------------*/
  for (curr_tbl = RamGlobals[i].files_tbl; curr_tbl; curr_tbl = next_tbl)
  {
    next_tbl = curr_tbl->next_tbl;
    curr_tbl->next_tbl = curr_tbl->prev_tbl = NULL;
    free_files(curr_tbl);
    free(curr_tbl);
  }
  RamGlobals[i].files_tbl = NULL;

  /*-------------------------------------------------------------------*/
  /* Reset state variables.                                            */
  /*-------------------------------------------------------------------*/
  Ram->fileno_gen = Ram->total_free = 0;
  Ram->num_sects = (ui32)-1;
  Ram->opendirs = 0;

  /*-------------------------------------------------------------------*/
  /* Release exclusive acess to TargetRFS and return success.          */
  /*-------------------------------------------------------------------*/
  semPost(RamSem);
  return 0;
}

/***********************************************************************/
/*   RfsAddVol: Add a new RAM volume                                   */
/*                                                                     */
/*       Input: name = volume name                                     */
/*                                                                     */
/*     Returns: 0 on success, -1 on error                              */
/*                                                                     */
/***********************************************************************/
int RfsAddVol(const char *name)
{
  int i, r_value = -1;
  RamGlob *vol = NULL;
  RFSEnt *v_ent;
  Module fp;

  /*-------------------------------------------------------------------*/
  /* If the volume name is invalid, return error.                      */
  /*-------------------------------------------------------------------*/
  if (InvalidName(name, FALSE))
  {
    set_errno(EINVAL);
    return r_value;
  }

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive access to upper file system.                    */
  /*-------------------------------------------------------------------*/
  semPend(FileSysSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive acess to the RAM file system.                   */
  /*-------------------------------------------------------------------*/
  semPend(RamSem, WAIT_FOREVER);

  /*-------------------------------------------------------------------*/
  /* First look that there is no name duplication.                     */
  /*-------------------------------------------------------------------*/
  for (i = 0; ; ++i)
  {
    fp = ModuleList[i];
    if (fp == NULL)
      break;

    if (fp(kVolName, name))
    {
      semPost(FileSysSem);
      set_errno(EEXIST);
      goto RamAddVol_error_exit;
    }
  }

  /*-------------------------------------------------------------------*/
  /* Release exclusive access to upper file system.                    */
  /*-------------------------------------------------------------------*/
  semPost(FileSysSem);

  /*-------------------------------------------------------------------*/
  /* Look for an empty entry in the RamGlobals array to place new      */
  /* volume controls.                                                  */
  /*-------------------------------------------------------------------*/
  for (i = 0;; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* If no space, set errno and go to exit.                          */
    /*-----------------------------------------------------------------*/
    if (i == NUM_RFS_VOLS)
    {
      set_errno(ENOMEM);
      goto RamAddVol_error_exit;
    }

    if (RamGlobals[i].num_sects == (ui32)-1)
    {
      vol = &RamGlobals[i];
      break;
    }
  }

  /*-------------------------------------------------------------------*/
  /* Attempt to allocate memory for the first files table.             */
  /*-------------------------------------------------------------------*/
  vol->files_tbl = GetRamTable();
  if (vol->files_tbl == NULL)
    goto RamAddVol_error_exit;

  /*-------------------------------------------------------------------*/
  /* Set the sys node so it can later be added to the mounted list.    */
  /*-------------------------------------------------------------------*/
  vol->sys.volume = vol;
  vol->sys.ioctl = RamIoctl;
  if (strlen(name) >= FILENAME_MAX)
  {
    set_errno(ENAMETOOLONG);
    goto RamAddVol_error_exit;
  }
  strcpy(vol->sys.name, name);

  /*-------------------------------------------------------------------*/
  /* First two entries in the files table are reserved for root.       */
  /*-------------------------------------------------------------------*/
  vol->files_tbl->free -= 1;

  /*-------------------------------------------------------------------*/
  /* Get pointer to the second entry in the files table.               */
  /*-------------------------------------------------------------------*/
  v_ent = &vol->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.frst_sect = NULL;
  v_ent->entry.comm.last_sect = NULL;
  v_ent->entry.comm.mod_time = v_ent->entry.comm.ac_time = OsSecCount;
  v_ent->entry.comm.fileno = vol->fileno_gen++;
  v_ent->entry.comm.one_past_last = 0;
  v_ent->entry.comm.addr = v_ent;

  /*-------------------------------------------------------------------*/
  /* Get pointer to the first entry in the files table.                */
  /*-------------------------------------------------------------------*/
  v_ent = &vol->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 = &vol->files_tbl->tbl[1].entry.comm;
  v_ent->entry.dir.parent_dir = NULL;
  v_ent->entry.dir.first = NULL;
  strncpy(v_ent->entry.dir.name, vol->sys.name, FILENAME_MAX);

  /*-------------------------------------------------------------------*/
  /* Set the other variables for this volume.                          */
  /*-------------------------------------------------------------------*/
  vol->total_free = FNUM_ENT - 2;
  vol->num_sects = 0;

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

  /*-------------------------------------------------------------------*/
  /* Release exclusive access to TargetRFS and return success.         */
  /*-------------------------------------------------------------------*/
  semPost(RamSem);
  return 0;

  /*-------------------------------------------------------------------*/
  /* In case of error, clean exit.                                     */
  /*-------------------------------------------------------------------*/
RamAddVol_error_exit:
  if (vol)
  {
    if (vol->files_tbl)
    {
      free(vol->files_tbl);
      vol->files_tbl = NULL;
    }
    vol->num_sects = vol->total_free = 0;
  }
  semPost(RamSem);
  return -1;
}
#endif /* NUM_RFS_VOLS */

⌨️ 快捷键说明

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