📄 fat_in.c
字号:
/*
**********************************************************************
* 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;
FS_u32 j;
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -