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

📄 fswrite.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      /*---------------------------------------------------------------*/
      remaining -= space_left;
      buf += space_left;

      /*---------------------------------------------------------------*/
      /* Adjust current offset.                                        */
      /*---------------------------------------------------------------*/
      stream->curr_ptr.offset = 0;

      /*---------------------------------------------------------------*/
      /* If this is the last sector, adjust both current sector number */
      /* and one past last sector number.                              */
      /*---------------------------------------------------------------*/
      if (stream->curr_ptr.sector == link_ptr->comm->last_sect)
      {
        /*-------------------------------------------------------------*/
        /* Adjust file size.                                           */
        /*-------------------------------------------------------------*/
        if (link_ptr->comm->one_past_last.sector != (ui16)-1)
          link_ptr->comm->size += (Flash->sect_sz -
                                   link_ptr->comm->one_past_last.offset);
        stream->curr_ptr.sector = (ui16)-1;
        link_ptr->comm->one_past_last.sector = (ui16)-1;
        link_ptr->comm->one_past_last.offset = 0;
      }

      /*---------------------------------------------------------------*/
      /* Else set current sector number to the next sector.            */
      /*---------------------------------------------------------------*/
      else
      {
        stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
        ++stream->curr_ptr.sect_off;
      }

      /*---------------------------------------------------------------*/
      /* Free current sector because we're moving to new one. Also     */
      /* need to check for recycles at this point.                     */
      /*---------------------------------------------------------------*/
      if (FreeSector(&stream->cached, &Flash->cache))
        return -1;
      check_recycles = TRUE;
    }

    /*-----------------------------------------------------------------*/
    /* Check for recycles if we need to.                               */
    /*-----------------------------------------------------------------*/
    if (check_recycles && FlashRecChck(SKIP_CHECK_FULL) ==RECYCLE_FAILED)
      return (int)(len - remaining);
  }

  /*-------------------------------------------------------------------*/
  /* Figure out how many new sectors are needed to write what's left.  */
  /*-------------------------------------------------------------------*/
  num_sectors = (remaining + Flash->sect_sz - 1) / Flash->sect_sz;

  /*-------------------------------------------------------------------*/
  /* Loop through the number of sectors, either getting existing ones  */
  /* or creating new ones.                                             */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < num_sectors; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* The cache entry should always be NULL because we're doing whole */
    /* sector writes.                                                  */
    /*-----------------------------------------------------------------*/
    PfAssert(stream->cached == NULL);

    /*-----------------------------------------------------------------*/
    /* If current pointer is at the end of the file, get new sector.   */
    /*-----------------------------------------------------------------*/
    if (stream->curr_ptr.sector == (ui16)-1)
    {
      /*---------------------------------------------------------------*/
      /* If file was created by creatn(), cannot expand it.            */
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->mode & S_CREATN)
      {
        set_errno(ENOSPC);
        return (int)(len - remaining);
      }

#if QUOTA_ENABLED
      /*---------------------------------------------------------------*/
      /* If quotas enabled, check if new sector(s) can be added to file*/
      /*---------------------------------------------------------------*/
      if (Flash->quota_enabled && adjust_quota)
      {
        if (link_ptr->parent_dir->entry.dir.free < (num_sectors - i) *
            Flash->sect_sz)
        {
          set_errno(ENOMEM);
          return (int)(len - remaining);
        }
      }
#endif /* QUOTA_ENABLED */

      /*---------------------------------------------------------------*/
      /* Set free sector to point where we can write to it.            */
      /*---------------------------------------------------------------*/
      if (FlashFrSect(link_ptr->comm))
        return (int)(len - remaining);

      /*---------------------------------------------------------------*/
      /* Set the dirty flag to dirty new because it's a new sector.    */
      /* Also, set the stream modified flag.                           */
      /*---------------------------------------------------------------*/
      dirty_flag = DIRTY_NEW;
      Flash->cache.dirty_new = TRUE;
      stream->flags |= FCB_MOD;

      /*---------------------------------------------------------------*/
      /* Reserve a free sector.                                        */
      /*---------------------------------------------------------------*/
      sect_num = Flash->free_sect;
      if (Flash->sect_tbl[sect_num].next == FLAST_SECT)
      {
        PfAssert(FALSE); /*lint !e506, !e774*/
        return -1;
      }
      Flash->free_sect = Flash->sect_tbl[sect_num].next;
      --Flash->free_sects;
      PfAssert(Flash->sect_tbl[sect_num].prev == FFREE_SECT);

      /*---------------------------------------------------------------*/
      /* This sector will be used, so mark both the total and block    */
      /* used counts.                                                  */
      /*---------------------------------------------------------------*/
      ++Flash->used_sects;
      ++Flash->blocks[sect_num / Flash->block_sects].used_sects;

      /*---------------------------------------------------------------*/
      /* Set the free sector to LAST because this sector will be last  */
      /* sector in the list of sectors belonging to the file.          */
      /*---------------------------------------------------------------*/
      Flash->sect_tbl[sect_num].next = FLAST_SECT;

      /*---------------------------------------------------------------*/
      /* If the file is empty, set first sector to sect_num, else set  */
      /* the current last to point to new last.                        */
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->frst_sect == FFREE_SECT)
      {
        link_ptr->comm->frst_sect = (ui16)sect_num;
        Flash->sect_tbl[sect_num].prev = FLAST_SECT;
        FlashUpdateFCBs(stream, link_ptr->comm);
      }
      else
      {
        /*-------------------------------------------------------------*/
        /* Set the entry in the sector table for the last sector.      */
        /*-------------------------------------------------------------*/
        Flash->sect_tbl[link_ptr->comm->last_sect].next = (ui16)sect_num;
        Flash->sect_tbl[sect_num].prev = link_ptr->comm->last_sect;

        /*-------------------------------------------------------------*/
        /* Increment current number of sectors here and not outside    */
        /* the if-else because we only increment for non-zero files,   */
        /* that is for files for which we're not creating the first    */
        /* sector. The reason being that sect_off = 0 identifies both  */
        /* an empty file and a file with 1 sector.                     */
        /*-------------------------------------------------------------*/
        ++stream->curr_ptr.sect_off;
      }

      /*---------------------------------------------------------------*/
      /* Update last sector pointer.                                   */
      /*---------------------------------------------------------------*/
      link_ptr->comm->last_sect = (ui16)sect_num;

      /*---------------------------------------------------------------*/
      /* Update current pointer and one past last.                     */
      /*---------------------------------------------------------------*/
      link_ptr->comm->one_past_last.sector = (ui16)sect_num;
      link_ptr->comm->one_past_last.offset = 0;
      stream->curr_ptr.sector = (ui16)sect_num;
      stream->curr_ptr.offset = 0;

      /*---------------------------------------------------------------*/
      /* Set the add size factor to 1 so that file size increases.     */
      /*---------------------------------------------------------------*/
      adjust_size = TRUE;

      /*---------------------------------------------------------------*/
      /* Skip reading because it's a new sector.                       */
      /*---------------------------------------------------------------*/
      skip_read = TRUE;

#if QUOTA_ENABLED
      /*---------------------------------------------------------------*/
      /* If quotas enabled, adjust quota values due to new sector(s).  */
      /*---------------------------------------------------------------*/
      if (Flash->quota_enabled && adjust_quota)
      {
        FFSEnt *ent, *root = &Flash->files_tbl->tbl[0];

        /*-------------------------------------------------------------*/
        /* Update used from parent to root.                            */
        /*-------------------------------------------------------------*/
        for (ent = link_ptr->parent_dir; ent;
             ent = ent->entry.dir.parent_dir)
        {
          PfAssert(ent->type == FDIREN);
          ent->entry.dir.used += (num_sectors - i) * Flash->sect_sz;
        }

        /*-------------------------------------------------------------*/
        /* Update free below.                                          */
        /*-------------------------------------------------------------*/
        FlashFreeBelow(root);

        /*-------------------------------------------------------------*/
        /* Recompute free at each node.                                */
        /*-------------------------------------------------------------*/
        FlashFree(root, root->entry.dir.max_q - FlashVirtUsed(root));

        /*-------------------------------------------------------------*/
        /* Set flag to skip adjusting since we've done it here.        */
        /*-------------------------------------------------------------*/
        adjust_quota = FALSE;
      }

⌨️ 快捷键说明

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