/* Filesystem object structure (FATFS) */
typedef struct {
BYTEfs_type;/* Filesystem type (0:not mounted) */
BYTEpdrv;/* Associated physical drive */
BYTEn_fats;/* Number of FATs (1 or 2) */
BYTEwflag;/* win[] flag (b0:dirty) */
BYTEfsi_flag;/* FSINFO flags (b7:disabled, b0:dirty) */
WORDid;/* Volume mount ID */
WORDn_rootdir;/* Number of root directory entries (FAT12/16) */
WORDcsize;/* Cluster size [sectors] */
#if FF_MAX_SS != FF_MIN_SS
size_tssize;/* Sector size (512, 1024, 2048 or 4096) */
#endif
#if FF_USE_LFN
WCHAR*lfnbuf;/* LFN working buffer */
#endif
#if FF_FS_REENTRANT
FF_SYNC_tsobj;/* Identifier of sync object */
#endif
#if !FF_FS_READONLY
DWORDlast_clst;/* Last allocated cluster */
DWORDfree_clst;/* Number of free clusters */
#endif
#if FF_FS_RPATH
DWORDcdir;/* Current directory start cluster (0:root) */
#endif
DWORDn_fatent;/* Number of FAT entries, = number of clusters + 2 */
DWORDfsize;/* Sectors per FAT */
LBA_tvolbase;/* Volume base sector */
LBA_tfatbase;/* FAT base sector */
LBA_tdirbase;/* Root directory base sector/cluster */
LBA_tdatabase;/* Data base sector */
LBA_twinsect;/* Current sector appearing in the win[] */
BYTE*win;/* Disk access window for Directory, FAT (and file data at tiny cfg) */
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
DWORDst_clst;
DWORDct_clst;
BYTEvir_flag;/* Flag of Virtual Filesystem Object, b0 : 1 for virtual Fatfs object, 0 for reality Fatfs object */
BYTEvir_avail;
DWORDvir_amount;
VOID*parent_fs;/* Point to the reality Fatfs object, only available in virtual Fatfs object */
CHARnamelabel[_MAX_ENTRYLENGTH + 1]; /* The name label point to the each virtual Fatfs object ,only available in virtual Fatfs obj */
VOID**child_fs;/* Point to the child Fatfs object ,only available in reality Fatfs object */
#endif
#ifndef __LITEOS_M__
int fs_uid;
int fs_gid;
mode_t fs_mode;
#endif
unsigned short fs_dmask;
unsigned short fs_fmask;
} FATFS;
/* Object ID and allocation information (FFOBJID) */
typedef struct {
FATFS*fs;/* Pointer to the hosting volume of this object */
WORDid;/* Hosting volume mount ID */
BYTEattr;/* Object attribute */
BYTEstat;/* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORDsclust;/* Object data start cluster (0:no cluster or root directory) */
FSIZE_tobjsize;/* Object size (valid when sclust != 0) */
#if FF_FS_LOCK
UINTlockid;/* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} FFOBJID;
/* File object structure (FIL) */
typedef struct {
FFOBJIDobj;/* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTEflag;/* File status flags */
BYTEerr;/* Abort flag (error code) */
FSIZE_tfptr;/* File read/write pointer (Zeroed on file open) */
DWORDclust;/* Current cluster of fpter (invalid when fptr is 0) */
LBA_tsect;/* Sector number appearing in buf[] (0:invalid) */
#if !FF_FS_READONLY
LBA_tdir_sect;/* Sector number containing the directory entry */
BYTE*dir_ptr;/* Pointer to the directory entry in the win[] */
#endif
#if FF_USE_FASTSEEK
DWORD*cltbl;/* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !FF_FS_TINY
BYTE*buf;/* File private data read/write window */
#endif
#ifndef __LITEOS_M__
LOS_DL_LIST fp_entry;
#endif
} FIL;
/* Directory object structure (DIR) */
struct __dirstream {
FFOBJIDobj;/* Object identifier */
DWORDdptr;/* Current read/write offset */
DWORDclust;/* Current cluster */
LBA_tsect;/* Current sector (0:Read operation has terminated) */
BYTE*dir;/* Pointer to the directory item in the win[] */
BYTEfn[12];/* SFN (in/out) {body[8],ext[3],status[1]} */
#if FF_USE_LFN
DWORDblk_ofs;/* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if FF_USE_FIND
const TCHAR* pat;/* Pointer to the name matching pattern */
#endif
#ifdef LOSCFG_FS_FAT_VIRTUAL_PARTITION
BYTEatrootdir;
#endif
};
结构体FILINFO用于维护文件信息,包含文件修改时间,大小和文件名等信息。
/* File information structure (FILINFO) */
typedef struct {
FSIZE_tfsize;/* File size */
WORDfdate;/* Modified date */
WORDftime;/* Modified time */
BYTEfattrib;/* File attribute */
#if FF_USE_LFN
TCHARaltname[FF_SFN_BUF + 1];/* Altenative file name */
TCHARfname[FF_LFN_BUF + 1];/* Primary file name */
#else
TCHARfname[12 + 1];/* File name */
#endif
DWORDsclst;
#ifndef __LITEOS_M__
LOS_DL_LIST fp_list;
#endif
} FILINFO;
static int FsChangeDrive(const char *path)
{
INT32 res;
⑴ CHAR tmpPath[FS_DRIVE_NAME_MAX_LEN] = { "/" }; /* the max name length of different parts is 16 */
errno_t retErr;
UINT16 pathLen;
pathLen = strlen((char const *)path);
/* make sure the path begin with "/", the path like /xxx/yyy/... */
⑵ if (pathLen >= (FS_DRIVE_NAME_MAX_LEN - 1)) {
/* 2: except first flag "/" and last end flag */
pathLen = FS_DRIVE_NAME_MAX_LEN - 2;
}
⑶ retErr = strncpy_s(tmpPath + 1, (FS_DRIVE_NAME_MAX_LEN - 1), (char const *)path, pathLen);
if (retErr != EOK) {
return FS_FAILURE;
}
res = f_chdrive(tmpPath);
if (res != FR_OK) {
return FS_FAILURE;
}
return FS_SUCCESS;
}
static unsigned int FatFsGetMode(int oflags)
{
UINT32 fmode = FA_READ;
if ((UINT32)oflags & O_WRONLY) {
fmode |= FA_WRITE;
}
if (((UINT32)oflags & O_ACCMODE) & O_RDWR) {
fmode |= FA_WRITE;
}
/* Creates a new file if the file is not existing, otherwise, just open it. */
if ((UINT32)oflags & O_CREAT) {
fmode |= FA_OPEN_ALWAYS;
/* Creates a new file. If the file already exists, the function shall fail. */
if ((UINT32)oflags & O_EXCL) {
fmode |= FA_CREATE_NEW;
}
}
/* Creates a new file. If the file already exists, its length shall be truncated to 0. */
if ((UINT32)oflags & O_TRUNC) {
fmode |= FA_CREATE_ALWAYS;
}
return fmode;
}
static int FatfsErrno(int result)
{
INT32 status = 0;
if (result < 0) {
return result;
}
/* FatFs errno to Libc errno */
switch (result) {
case FR_OK:
break;
case FR_NO_FILE:
case FR_NO_PATH:
case FR_NO_FILESYSTEM:
status = ENOENT;
break;
......
default:
status = result;
break;
}
return status;
}