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

📄 fsread.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      /* sector to read from.                                          */
      /*---------------------------------------------------------------*/
      if (stream->curr_ptr.sector == link_ptr->comm->last_sect)
      {
        stream->curr_ptr.sector = link_ptr->comm->one_past_last.sector;
        stream->curr_ptr.offset = link_ptr->comm->one_past_last.offset;
        unfinished = TRUE;
        goto read_exit;
      }
      else
      {
        stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
        ++stream->curr_ptr.sect_off;
      }

      /*---------------------------------------------------------------*/
      /* Free current sector because we're done reading from it.       */
      /*---------------------------------------------------------------*/
      FreeSector(&stream->cached, &Flash->cache);
    }
  }

  /*-------------------------------------------------------------------*/
  /* Figure out how many sectors need to be read.                      */
  /*-------------------------------------------------------------------*/
  num_sectors = (remaining + Flash->sect_sz - 1) / Flash->sect_sz;

  /*-------------------------------------------------------------------*/
  /* Loop through number of sectors, reading them in one at a time.    */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < num_sectors; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* Get pointer to the cached sector entry.                         */
    /*-----------------------------------------------------------------*/
    status = GetSector(&Flash->cache, (int)stream->curr_ptr.sector,
                       FALSE, link_ptr->comm, &stream->cached);
    if (status == GET_WRITE_ERROR)
    {
      len -= remaining;
      goto read_exit;
    }

    /*-----------------------------------------------------------------*/
    /* Get pointer to the sector data.                                 */
    /*-----------------------------------------------------------------*/
    sector = ((CacheEntry *)stream->cached)->sector;

    /*-----------------------------------------------------------------*/
    /* If what's left to be read is from this sector, it's the last    */
    /* sector to be read (maybe only partially).                       */
    /*-----------------------------------------------------------------*/
    if (remaining <= Flash->sect_sz)
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, set    */
      /* unfinished flag and read as much as possible.                 */
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->one_past_last.sector ==
                                               stream->curr_ptr.sector &&
          link_ptr->comm->one_past_last.offset < (int)remaining)
      {
        unfinished = TRUE;
        len -= (remaining - link_ptr->comm->one_past_last.offset);
        remaining = link_ptr->comm->one_past_last.offset;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to read everything that's left from this sector.   */
      /*---------------------------------------------------------------*/
      memcpy(buf, sector, remaining);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len -= remaining;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Adjust current pointer.                                       */
      /*---------------------------------------------------------------*/
      if (remaining == Flash->sect_sz)
      {
        stream->curr_ptr.offset = 0;

        /*-------------------------------------------------------------*/
        /* If this is the last sector, set current sector number to    */
        /* invalid (-1), else set it to the next sector in the file.   */
        /*-------------------------------------------------------------*/
        if (link_ptr->comm->last_sect == stream->curr_ptr.sector)
          stream->curr_ptr.sector = (ui16)-1;
        else
        {
          stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
          ++stream->curr_ptr.sect_off;
        }

        /*-------------------------------------------------------------*/
        /* Free current sector because we're done reading from it.     */
        /*-------------------------------------------------------------*/
        FreeSector(&stream->cached, &Flash->cache);
      }
      else
        stream->curr_ptr.offset = (ui16)remaining;

      /*---------------------------------------------------------------*/
      /* We're done reading so return.                                 */
      /*---------------------------------------------------------------*/
      goto read_exit;
    }

    /*-----------------------------------------------------------------*/
    /* Else more than one sector remains to be read.                   */
    /*-----------------------------------------------------------------*/
    else
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, set    */
      /* unfinished flag and read as much as possible before returning.*/
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->last_sect == stream->curr_ptr.sector)
      {
        unfinished = TRUE;
        if (link_ptr->comm->one_past_last.offset)
          full_len = link_ptr->comm->one_past_last.offset;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to read the whole sector.                          */
      /*---------------------------------------------------------------*/
      memcpy(buf, sector, full_len);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len -= remaining;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Update remaining and buf.                                     */
      /*---------------------------------------------------------------*/
      remaining -= full_len;
      buf += full_len;

      /*---------------------------------------------------------------*/
      /* Free current sector because we're done reading from it.       */
      /*---------------------------------------------------------------*/
      FreeSector(&stream->cached, &Flash->cache);

      /*---------------------------------------------------------------*/
      /* If no more sectors stop, else go to next sector in file.      */
      /*---------------------------------------------------------------*/
      if (unfinished)
      {
        stream->curr_ptr.sector = link_ptr->comm->one_past_last.sector;
        stream->curr_ptr.offset = link_ptr->comm->one_past_last.offset;
        len -= remaining;
        goto read_exit;
      }
      else
      {
        stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
        ++stream->curr_ptr.sect_off;
        stream->curr_ptr.offset = 0;
      }
    }
  }

  /*-------------------------------------------------------------------*/
  /* Before returning, mark access time and, if read could not be      */
  /* finished, free current sector.                                    */
  /*-------------------------------------------------------------------*/
read_exit:
  link_ptr->comm->ac_time = OsSecCount;
  if (unfinished && stream->cached)
    FreeSector(&stream->cached, &Flash->cache);

  return (int)len;
}
#endif /* NUM_FFS_VOLS */

⌨️ 快捷键说明

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