fat_in.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:6k
- /*
- **********************************************************************
- * Micrium, Inc.
- * 949 Crestview Circle
- * Weston, FL 33327-1848
- *
- * uC/FS
- *
- * (c) Copyright 2001 - 2003, Micrium, Inc.
- * All rights reserved.
- *
- ***********************************************************************
- ----------------------------------------------------------------------
- File : fat_in.c
- Purpose : FAT read routines
- ----------------------------------------------------------------------
- Known problems or limitations with current version
- ----------------------------------------------------------------------
- None.
- ---------------------------END-OF-HEADER------------------------------
- */
- /*********************************************************************
- *
- * #include Section
- *
- **********************************************************************
- */
- #include "fs_conf.h"
- #include "fs_port.h"
- #include "fs_dev.h"
- #include "fs_api.h"
- #include "fs_fsl.h"
- #include "fs_int.h"
- #include "fs_os.h"
- #include "fs_lbl.h"
- #include "fs_fat.h"
- /*********************************************************************
- *
- * Global functions
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * FS__fat_fread
- *
- Description:
- FS internal function. Read data from a file.
- Parameters:
- pData - Pointer to a data buffer for storing data transferred
- from file.
- Size - Size of an element to be transferred from file to data
- buffer
- N - Number of elements to be transferred from the file.
- pFile - Pointer to a FS_FILE data structure.
-
- Return value:
- Number of elements read.
- */
- FS_size_t FS__fat_fread(void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile) {
- FS_size_t todo;
- FS_u32 i = 0;
- FS_u32 j = 0;
- FS_u32 fatsize;
- FS_u32 fileclustnum;
- FS_u32 diskclustnum;
- FS_u32 prevclust;
- FS_u32 dstart;
- FS_u32 dsize;
- FS_u32 datastart;
- char *buffer;
- int err;
-
- if (!pFile) {
- return 0; /* No valid pointer to a FS_FILE structure */
- }
- /* Check if media is OK */
- err = FS__lb_status(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo);
- if (err == FS_LBL_MEDIACHANGED) {
- /* Media has changed */
- pFile->error = FS_ERR_DISKCHANGED;
- return 0;
- }
- else if (err < 0) {
- /* Media cannot be accessed */
- pFile->error = FS_ERR_READERROR;
- return 0;
- }
- buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
- if (!buffer) {
- return 0;
- }
- fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz16;
- if (fatsize == 0) {
- /* FAT32 */
- fatsize = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].FATSz32;
- }
- dstart = FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RsvdSecCnt + FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].NumFATs * fatsize;
- dsize = ((FS_u32)((FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].RootEntCnt) * FS_FAT_DENTRY_SIZE) / FS_FAT_SEC_SIZE;
- datastart = dstart + dsize;
- prevclust = 0;
- todo = N * Size;
- while (todo) {
- if (pFile->filepos >= pFile->size) {
- /* EOF has been reached */
- pFile->error = FS_ERR_EOF;
- FS__fat_free(buffer);
- return ((N * Size - todo) / Size);
- }
- fileclustnum = pFile->filepos / (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus);
- if (prevclust == 0) {
- diskclustnum = pFile->CurClust;
- if (diskclustnum == 0) {
- /* Find current cluster by starting at 1st cluster of the file */
- diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, pFile->fileid_hi, fileclustnum);
- }
- }
- else {
- /* Get next cluster of the file */
- diskclustnum = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
- }
- prevclust = diskclustnum;
- pFile->CurClust = diskclustnum;
- if (diskclustnum == 0) {
- /* Could not find current cluster */
- pFile->error = FS_ERR_READERROR;
- FS__fat_free(buffer);
- return ((N * Size - todo) / Size);
- }
- diskclustnum -= 2;
- j = (pFile->filepos % (FS_FAT_SEC_SIZE * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus))/ FS_FAT_SEC_SIZE;
- while (1) {
- if (!todo) {
- break; /* Nothing more to write */
- }
- if (j >= (FS_u32)FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
- break; /* End of the cluster reached */
- }
- if (pFile->filepos >= pFile->size) {
- break; /* End of the file reached */
- }
- err = FS__lb_read(FS__pDevInfo[pFile->dev_index].devdriver, pFile->fileid_lo,
- datastart +
- diskclustnum * FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus + j,
- (void*)buffer);
- if (err < 0) {
- pFile->error = FS_ERR_READERROR;
- FS__fat_free(buffer);
- return ((N * Size - todo) / Size);
- }
- i = pFile->filepos % FS_FAT_SEC_SIZE;
- while (1) {
- if (!todo) {
- break; /* Nothing more to write */
- }
- if (i >= FS_FAT_SEC_SIZE) {
- break; /* End of the sector reached */
- }
- if (pFile->filepos >= pFile->size) {
- break; /* End of the file reached */
- }
- *((char*)(((char*)pData) + N * Size - todo)) = buffer[i];
- i++;
- pFile->filepos++;
- todo--;
- }
- j++;
- } /* Sector loop */
- } /* Cluster loop */
- if (i >= FS_FAT_SEC_SIZE) {
- if (j >= FS__FAT_aBPBUnit[pFile->dev_index][pFile->fileid_lo].SecPerClus) {
- pFile->CurClust = FS__fat_diskclust(pFile->dev_index, pFile->fileid_lo, prevclust, 1);
- }
- }
- FS__fat_free(buffer);
- return ((N * Size - todo) / Size);
- }