📄 tff.i
字号:
} FIL;
/* File status structure */
typedef struct _FILINFO {
DWORD fsize; /* Size */
WORD fdate; /* Date */
WORD ftime; /* Time */
BYTE fattrib; /* Attribute */
char fname[8+1+3+1]; /* Name (8.3 format) */
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_NOT_READY, /* 1 */
FR_NO_FILE, /* 2 */
FR_NO_PATH, /* 3 */
FR_INVALID_NAME, /* 4 */
FR_INVALID_DRIVE, /* 5 */
FR_DENIED, /* 6 */
FR_EXIST, /* 7 */
FR_RW_ERROR, /* 8 */
FR_WRITE_PROTECTED, /* 9 */
FR_NOT_ENABLED, /* 10 */
FR_NO_FILESYSTEM, /* 11 */
FR_INVALID_OBJECT, /* 12 */
FR_MKFS_ABORTED /* 13 (not used) */
} FRESULT;
/*-----------------------------------------------------*/
/* Tiny-FatFs module application interface */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*); /* Truncate file */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
FRESULT f_mkdir (const char*); /* Create a new directory */
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change file/dir attriburte */
FRESULT f_utime (const char*, const FILINFO*); /* Change file/dir timestamp */
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
/* User defined function to give a current time to fatfs module */
DWORD get_fattime (void); /* 31-25: Year(0-127 +1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
/* File access control and file status flags (FIL.flag) */
/* FAT sub type (FATFS.fs_type) */
/* File attribute bits for directory entry */
/* Offset of FAT structure members */
/* Multi-byte word access macros */
/*-----------------------------------------------------------------------
/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007
/----------------------------------------------------------------------- */
/* Status of Disk Functions */
typedef BYTE DSTATUS;
typedef BYTE DSTATUS;
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE);
DSTATUS disk_status (BYTE);
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
DRESULT disk_ioctl (BYTE, BYTE, void*);
void disk_timerproc (void);
/* Disk Status Bits (DSTATUS) */
/* Command code for disk_ioctrl() */
/* Generic command */
/* MMC/SDC command */
/* ATA/CF command */
static
FATFS *FatFs; /* Pointer to the file system objects (logical drive) */
static
WORD fsid; /* File system mount ID */
/*-------------------------------------------------------------------------
Module Private Functions
-------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Change window offset */
/*-----------------------------------------------------------------------*/
static
BOOL move_window ( /* TRUE: successful, FALSE: failed */
DWORD sector /* Sector number to make apperance in the FatFs->win */
) /* Move to zero only writes back dirty window */
{
DWORD wsect;
FATFS *fs = FatFs;
wsect = fs->winsect;
if (wsect != sector) { /* Changed current window */
BYTE n;
if (fs->winflag) { /* Write back dirty window if needed */
if (disk_write(0, fs->win, wsect, 1) != RES_OK)
return 0;
fs->winflag = 0;
if (wsect < (fs->fatbase + fs->sects_fat)) { /* In FAT area */
for (n = fs->n_fats; n >= 2; n--) { /* Refrect the change to all FAT copies */
wsect += fs->sects_fat;
disk_write(0, fs->win, wsect, 1);
}
}
}
if (sector) {
if (disk_read(0, fs->win, sector, 1) != RES_OK)
return 0;
fs->winsect = sector;
}
}
return 1;
}
DWORD get_fattime ()
{
return 1;
}
/*-----------------------------------------------------------------------*/
/* Clean-up cached data */
/*-----------------------------------------------------------------------*/
static
FRESULT sync (void) /* FR_OK: successful, FR_RW_ERROR: failed */
{
FATFS *fs = FatFs;
fs->winflag = 1;
if (!move_window(0)) return FR_RW_ERROR;
/* Update FSInfo sector if needed */
if (fs->fs_type == 3 && fs->fsi_flag) {
fs->winsect = 0;
memset(fs->win, 0, 512U);
*(volatile BYTE*)(&fs->win[510])=(BYTE)(0xAA55); *(volatile BYTE*)((&fs->win[510])+1)=(BYTE)((WORD)(0xAA55)>>8);
*(volatile BYTE*)(&fs->win[0])=(BYTE)(0x41615252); *(volatile BYTE*)((&fs->win[0])+1)=(BYTE)((WORD)(0x41615252)>>8); *(volatile BYTE*)((&fs->win[0])+2)=(BYTE)((DWORD)(0x41615252)>>16); *(volatile BYTE*)((&fs->win[0])+3)=(BYTE)((DWORD)(0x41615252)>>24);
*(volatile BYTE*)(&fs->win[484])=(BYTE)(0x61417272); *(volatile BYTE*)((&fs->win[484])+1)=(BYTE)((WORD)(0x61417272)>>8); *(volatile BYTE*)((&fs->win[484])+2)=(BYTE)((DWORD)(0x61417272)>>16); *(volatile BYTE*)((&fs->win[484])+3)=(BYTE)((DWORD)(0x61417272)>>24);
*(volatile BYTE*)(&fs->win[488])=(BYTE)(fs->free_clust); *(volatile BYTE*)((&fs->win[488])+1)=(BYTE)((WORD)(fs->free_clust)>>8); *(volatile BYTE*)((&fs->win[488])+2)=(BYTE)((DWORD)(fs->free_clust)>>16); *(volatile BYTE*)((&fs->win[488])+3)=(BYTE)((DWORD)(fs->free_clust)>>24);
*(volatile BYTE*)(&fs->win[492])=(BYTE)(fs->last_clust); *(volatile BYTE*)((&fs->win[492])+1)=(BYTE)((WORD)(fs->last_clust)>>8); *(volatile BYTE*)((&fs->win[492])+2)=(BYTE)((DWORD)(fs->last_clust)>>16); *(volatile BYTE*)((&fs->win[492])+3)=(BYTE)((DWORD)(fs->last_clust)>>24);
disk_write(0, fs->win, fs->fsi_sector, 1);
fs->fsi_flag = 0;
}
/* Make sure that no pending write process in the physical drive */
if (disk_ioctl(0, 0 , 0) != RES_OK)
return FR_RW_ERROR;
return FR_OK;
}
/*-----------------------------------------------------------------------*/
/* Get a cluster status */
/*-----------------------------------------------------------------------*/
static
CLUST get_cluster ( /* 0,>=2: successful, 1: failed */
CLUST clust /* Cluster# to get the link information */
)
{
WORD wc, bc;
DWORD fatsect;
FATFS *fs = FatFs;
if (clust >= 2 && clust < fs->max_clust) { /* Valid cluster# */
fatsect = fs->fatbase;
switch (fs->fs_type) {
case 1 :
bc = (WORD)clust * 3 / 2;
if (!move_window(fatsect + bc / 512U)) break;
wc = fs->win[bc % 512U]; bc++;
if (!move_window(fatsect + bc / 512U)) break;
wc |= (WORD)fs->win[bc % 512U] << 8;
return (clust & 1) ? (wc >> 4) : (wc & 0xFFF);
case 2 :
if (!move_window(fatsect + clust / 256)) break;
return (WORD)(((WORD)*(volatile BYTE*)((&fs->win[((WORD)clust * 2) % 512U])+1)<<8)|(WORD)*(volatile BYTE*)(&fs->win[((WORD)clust * 2) % 512U]));
case 3 :
if (!move_window(fatsect + clust / 128)) break;
return (DWORD)(((DWORD)*(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+3)<<24)|((DWORD)*(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+2)<<16)|((WORD)*(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+1)<<8)|*(volatile BYTE*)(&fs->win[((WORD)clust * 4) % 512U])) & 0x0FFFFFFF;
}
}
return 1; /* Out of cluster range, or an error occured */
}
/*-----------------------------------------------------------------------*/
/* Change a cluster status */
/*-----------------------------------------------------------------------*/
static
BOOL put_cluster ( /* TRUE: successful, FALSE: failed */
CLUST clust, /* Cluster# to change (must be 2 to fs->max_clust-1) */
CLUST val /* New value to mark the cluster */
)
{
WORD bc;
BYTE *p;
DWORD fatsect;
FATFS *fs = FatFs;
fatsect = fs->fatbase;
switch (fs->fs_type) {
case 1 :
bc = (WORD)clust * 3 / 2;
if (!move_window(fatsect + bc / 512U)) return 0;
p = &fs->win[bc % 512U];
*p = (clust & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
bc++;
fs->winflag = 1;
if (!move_window(fatsect + bc / 512U)) return 0;
p = &fs->win[bc % 512U];
*p = (clust & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
break;
case 2 :
if (!move_window(fatsect + clust / 256)) return 0;
*(volatile BYTE*)(&fs->win[((WORD)clust * 2) % 512U])=(BYTE)((WORD)val); *(volatile BYTE*)((&fs->win[((WORD)clust * 2) % 512U])+1)=(BYTE)((WORD)((WORD)val)>>8);
break;
case 3 :
if (!move_window(fatsect + clust / 128)) return 0;
*(volatile BYTE*)(&fs->win[((WORD)clust * 4) % 512U])=(BYTE)(val); *(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+1)=(BYTE)((WORD)(val)>>8); *(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+2)=(BYTE)((DWORD)(val)>>16); *(volatile BYTE*)((&fs->win[((WORD)clust * 4) % 512U])+3)=(BYTE)((DWORD)(val)>>24);
break;
default :
return 0;
}
fs->winflag = 1;
return 1;
}
/*-----------------------------------------------------------------------*/
/* Remove a cluster chain */
/*-----------------------------------------------------------------------*/
static
BOOL remove_chain ( /* TRUE: successful, FALSE: failed */
CLUST clust /* Cluster# to remove chain from */
)
{
CLUST nxt;
FATFS *fs = FatFs;
while (clust >= 2 && clust < fs->max_clust) {
nxt = get_cluster(clust);
if (nxt == 1) return 0;
if (!put_cluster(clust, 0)) return 0;
if (fs->free_clust != (CLUST)0xFFFFFFFF) {
fs->free_clust++;
fs->fsi_flag = 1;
}
clust = nxt;
}
return 1;
}
/*-----------------------------------------------------------------------*/
/* Stretch or create a cluster chain */
/*-----------------------------------------------------------------------*/
static
CLUST create_chain ( /* 0: No free cluster, 1: Error, >=2: New cluster number */
CLUST clust /* Cluster# to stretch, 0 means create new */
)
{
CLUST cstat, ncl, scl, mcl;
FATFS *fs = FatFs;
mcl = fs->max_clust;
if (clust == 0) { /* Create new chain */
scl = fs->last_clust; /* Get last allocated cluster */
if (scl < 2 || scl >= mcl) scl = 1;
}
else { /* Stretch existing chain */
cstat = get_cluster(clust); /* Check the cluster status */
if (cstat < 2) return 1; /* It is an invalid cluster */
if (cstat < mcl) return cstat; /* It is already followed by next cluster */
scl = clust;
}
ncl = scl; /* Start cluster */
for (;;) {
ncl++; /* Next cluster */
if (ncl >= mcl) { /* Wrap around */
ncl = 2;
if (ncl > scl) return 0; /* No free custer */
}
cstat = get_cluster(ncl); /* Get the cluster status */
if (cstat == 0) break; /* Found a free cluster */
if (cstat == 1) return 1; /* Any error occured */
if (ncl == scl) return 0; /* No free custer */
}
if (!put_cluster(ncl, (CLUST)0x0FFFFFFF)) return 1; /* Mark the new cluster "in use" */
if (clust != 0 && !put_cluster(clust, ncl)) return 1; /* Link it to previous one if needed */
fs->last_clust = ncl; /* Update fsinfo */
if (fs->free_clust != (CLUST)0xFFFFFFFF) {
fs->free_clust--;
fs->fsi_flag = 1;
}
return ncl; /* Return new cluster number */
}
/*-----------------------------------------------------------------------*/
/* Get sector# from cluster# */
/*-----------------------------------------------------------------------*/
static
DWORD clust2sect ( /* !=0: sector number, 0: failed - invalid cluster# */
CLUST clust /* Cluster# to be converted */
)
{
FATFS *fs = FatFs;
clust -= 2;
if (clust >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */
return (DWORD)clust * fs->csize + fs->database;
}
/*-----------------------------------------------------------------------*/
/* Move directory pointer to next */
/*-----------------------------------------------------------------------*/
static
BOOL next_dir_entry ( /* TRUE: successful, FALSE: could not move next */
DIR *dj /* Pointer to directory object */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -