fix open flags issue; update ELM FatFs to 007E;
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@407 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
034166dfb9
commit
2f3882c714
|
@ -1,8 +1,9 @@
|
||||||
FatFs Module Source Files R0.07c (C)ChaN, 2009
|
FatFs Module Source Files R0.07e (C)ChaN, 2009
|
||||||
|
|
||||||
|
|
||||||
FILES
|
FILES
|
||||||
|
|
||||||
|
ffconf.h Configuration file for FatFs module.
|
||||||
ff.h Common include file for FatFs and application module.
|
ff.h Common include file for FatFs and application module.
|
||||||
ff.c FatFs module.
|
ff.c FatFs module.
|
||||||
diskio.h Common include file for FatFs and disk I/O module.
|
diskio.h Common include file for FatFs and disk I/O module.
|
||||||
|
@ -100,5 +101,10 @@ REVISION HISTORY
|
||||||
Added relative path feature.
|
Added relative path feature.
|
||||||
Added f_chdir().
|
Added f_chdir().
|
||||||
Added f_chdrive().
|
Added f_chdrive().
|
||||||
Added proper case conversion to extended char.
|
Added proper case conversion for extended characters.
|
||||||
|
|
||||||
|
Nov 03,'2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||||
|
Added a configuration option, _LFN_UNICODE.
|
||||||
|
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||||
|
Fixed name matching error on the 13 char boundary.
|
||||||
|
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||||
|
|
|
@ -140,9 +140,13 @@ int dfs_elm_open(struct dfs_fd* file)
|
||||||
{
|
{
|
||||||
mode = FA_READ;
|
mode = FA_READ;
|
||||||
|
|
||||||
if (file->flags & DFS_O_CREAT) mode |= FA_CREATE_NEW;
|
|
||||||
if (file->flags & DFS_O_WRONLY) mode |= FA_WRITE;
|
if (file->flags & DFS_O_WRONLY) mode |= FA_WRITE;
|
||||||
|
/* Opens the file, if it is existing. If not, a new file is created. */
|
||||||
|
if (file->flags & DFS_O_CREAT) mode |= FA_OPEN_ALWAYS;
|
||||||
|
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
||||||
if (file->flags & DFS_O_TRUNC) mode |= FA_CREATE_ALWAYS;
|
if (file->flags & DFS_O_TRUNC) mode |= FA_CREATE_ALWAYS;
|
||||||
|
/* Creates a new file. The function fails if the file is already existing. */
|
||||||
|
if (file->flags & DFS_O_EXCL) mode |= FA_CREATE_NEW;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* allocate a fd */
|
||||||
fd = (FIL*)rt_malloc(sizeof(FIL));
|
fd = (FIL*)rt_malloc(sizeof(FIL));
|
||||||
|
@ -157,6 +161,11 @@ int dfs_elm_open(struct dfs_fd* file)
|
||||||
file->pos = fd->fptr;
|
file->pos = fd->fptr;
|
||||||
file->size = fd->fsize;
|
file->size = fd->fsize;
|
||||||
file->data = fd;
|
file->data = fd;
|
||||||
|
|
||||||
|
if (file->flags & DFS_O_APPEND)
|
||||||
|
{
|
||||||
|
file->pos = f_lseek(fd, fd->fsize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -458,3 +467,41 @@ rt_time_t get_fattime()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
BOOL ff_cre_syncobj(BYTE drv, _SYNC_t* m)
|
||||||
|
{
|
||||||
|
char name[8];
|
||||||
|
rt_mutex_t mutex;
|
||||||
|
|
||||||
|
rt_snprintf(name, sizeof(name), "fat%d", drv);
|
||||||
|
mutex = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
|
||||||
|
if (mutex != RT_NULL)
|
||||||
|
{
|
||||||
|
*m = mutex;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ff_del_syncobj(_SYNC_t m)
|
||||||
|
{
|
||||||
|
rt_mutex_delete(m);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ff_req_grant(_SYNC_t m)
|
||||||
|
{
|
||||||
|
if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK) return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_rel_grant(_SYNC_t m)
|
||||||
|
{
|
||||||
|
rt_mutex_release(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -49,7 +49,7 @@ DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||||
/* Generic command */
|
/* Generic command */
|
||||||
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
||||||
#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */
|
#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */
|
||||||
#define GET_SECTOR_SIZE 2
|
#define GET_SECTOR_SIZE 2 /* Mandatory for multiple sector size cfg */
|
||||||
#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */
|
#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */
|
||||||
#define CTRL_POWER 4
|
#define CTRL_POWER 4
|
||||||
#define CTRL_LOCK 5
|
#define CTRL_LOCK 5
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*----------------------------------------------------------------------------/
|
/*----------------------------------------------------------------------------/
|
||||||
/ FatFs - FAT file system module R0.07c (C)ChaN, 2009
|
/ FatFs - FAT file system module R0.07e (C)ChaN, 2009
|
||||||
/-----------------------------------------------------------------------------/
|
/-----------------------------------------------------------------------------/
|
||||||
/ FatFs module is an open source software to implement FAT file system to
|
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||||
/ small embedded systems. This is a free software and is opened for education,
|
/ This is a free software that opened for education, research and commercial
|
||||||
/ research and commercial use under license policy of following trems.
|
/ developments under license policy of following trems.
|
||||||
/
|
/
|
||||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||||
/
|
/
|
||||||
|
@ -63,11 +63,17 @@
|
||||||
/ Renamed string functions to avoid name collision.
|
/ Renamed string functions to avoid name collision.
|
||||||
/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
|
/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.
|
||||||
/ Added multiple sector size support.
|
/ Added multiple sector size support.
|
||||||
/ Jun 21,'09 R0.07c Fixed f_unlink() may return FR_OK on error.
|
/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error.
|
||||||
/ Fixed wrong cache control in f_lseek().
|
/ Fixed wrong cache control in f_lseek().
|
||||||
/ Added relative path feature.
|
/ Added relative path feature.
|
||||||
/ Added f_chdir() and f_chdrive().
|
/ Added f_chdir() and f_chdrive().
|
||||||
/ Added proper case conversion to extended char.
|
/ Added proper case conversion to extended char.
|
||||||
|
/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||||
|
/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||||
|
/ Fixed name matching error on the 13 char boundary.
|
||||||
|
/ Added a configuration option, _LFN_UNICODE.
|
||||||
|
/ Changed f_readdir() to return the SFN with always upper
|
||||||
|
/ case on non-LFN cfg.
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "ff.h" /* FatFs configurations and declarations */
|
#include "ff.h" /* FatFs configurations and declarations */
|
||||||
|
@ -79,6 +85,10 @@
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if _FATFS != 0x007E
|
||||||
|
#error Wrong include file (ff.h).
|
||||||
|
#endif
|
||||||
|
|
||||||
#if _FS_REENTRANT
|
#if _FS_REENTRANT
|
||||||
#if _USE_LFN == 1
|
#if _USE_LFN == 1
|
||||||
#error Static LFN work area must not be used in re-entrant configuration.
|
#error Static LFN work area must not be used in re-entrant configuration.
|
||||||
|
@ -99,7 +109,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Name status flags */
|
/* Name status flags */
|
||||||
#define NS_LOSS 0x01 /* Lossy conversion */
|
#define NS 11 /* Offset of name status byte */
|
||||||
|
#define NS_LOSS 0x01 /* Out of 8.3 format */
|
||||||
#define NS_LFN 0x02 /* Force to create LFN entry */
|
#define NS_LFN 0x02 /* Force to create LFN entry */
|
||||||
#define NS_LAST 0x04 /* Last segment */
|
#define NS_LAST 0x04 /* Last segment */
|
||||||
#define NS_BODY 0x08 /* Lower case flag (body) */
|
#define NS_BODY 0x08 /* Lower case flag (body) */
|
||||||
|
@ -115,6 +126,9 @@
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if _DRIVES < 1 || _DRIVES > 9
|
||||||
|
#error Number of drives must be 1-9.
|
||||||
|
#endif
|
||||||
static
|
static
|
||||||
FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */
|
FATFS *FatFs[_DRIVES]; /* Pointer to the file system objects (logical drives) */
|
||||||
|
|
||||||
|
@ -129,7 +143,7 @@ BYTE Drive; /* Current drive */
|
||||||
|
|
||||||
#if _USE_LFN == 1 /* LFN with static LFN working buffer */
|
#if _USE_LFN == 1 /* LFN with static LFN working buffer */
|
||||||
static
|
static
|
||||||
WORD LfnBuf[_MAX_LFN + 1];
|
WCHAR LfnBuf[_MAX_LFN + 1];
|
||||||
#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR *lp = LfnBuf
|
#define NAMEBUF(sp,lp) BYTE sp[12]; WCHAR *lp = LfnBuf
|
||||||
#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp
|
#define INITBUF(dj,sp,lp) dj.fn = sp; dj.lfn = lp
|
||||||
|
|
||||||
|
@ -148,7 +162,7 @@ WORD LfnBuf[_MAX_LFN + 1];
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
|
|
||||||
Private Functions
|
Module Private Functions
|
||||||
|
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -305,7 +319,7 @@ FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */
|
||||||
/* FAT access - Read value of a FAT entry */
|
/* FAT access - Read value of a FAT entry */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static
|
|
||||||
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
|
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
|
||||||
FATFS *fs, /* File system object */
|
FATFS *fs, /* File system object */
|
||||||
DWORD clst /* Cluster# to get the link information */
|
DWORD clst /* Cluster# to get the link information */
|
||||||
|
@ -347,7 +361,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status *
|
||||||
/* FAT access - Change value of a FAT entry */
|
/* FAT access - Change value of a FAT entry */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
#if !_FS_READONLY
|
#if !_FS_READONLY
|
||||||
static
|
|
||||||
FRESULT put_fat (
|
FRESULT put_fat (
|
||||||
FATFS *fs, /* File system object */
|
FATFS *fs, /* File system object */
|
||||||
DWORD clst, /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */
|
DWORD clst, /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */
|
||||||
|
@ -509,7 +523,7 @@ DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk err
|
||||||
/* Get sector# from cluster# */
|
/* Get sector# from cluster# */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static
|
|
||||||
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
|
||||||
FATFS *fs, /* File system object */
|
FATFS *fs, /* File system object */
|
||||||
DWORD clst /* Cluster# to be converted */
|
DWORD clst /* Cluster# to be converted */
|
||||||
|
@ -653,18 +667,26 @@ BOOL cmp_lfn ( /* TRUE:Matched, FALSE:Not matched */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i, s;
|
int i, s;
|
||||||
WCHAR wc;
|
WCHAR wc, uc;
|
||||||
|
|
||||||
|
|
||||||
i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */
|
i = ((dir[LDIR_Ord] & 0xBF) - 1) * 13; /* Get offset in the LFN buffer */
|
||||||
s = 0;
|
s = 0; wc = 1;
|
||||||
do {
|
do {
|
||||||
wc = ff_wtoupper(LD_WORD(dir+LfnOfs[s])); /* Get an LFN character */
|
uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
|
||||||
if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it with the reference character */
|
if (wc) { /* Last char has not been processed */
|
||||||
return FALSE;
|
wc = ff_wtoupper(uc); /* Convert it to upper case */
|
||||||
} while (++s < 13 && wc); /* Repeat until all chars in the entry or a NUL char is processed */
|
if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */
|
||||||
|
return FALSE; /* Not matched */
|
||||||
|
} else {
|
||||||
|
if (uc != 0xFFFF) return FALSE; /* Check filler */
|
||||||
|
}
|
||||||
|
} while (++s < 13); /* Repeat until all chars in the entry are checked */
|
||||||
|
|
||||||
return TRUE; /* The LFN entry matched */
|
if ((dir[LDIR_Ord] & 0x40) && wc && lfnbuf[i]) /* Last segment matched but different length */
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE; /* The part of LFN matched */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -676,18 +698,21 @@ BOOL pick_lfn ( /* TRUE:Succeeded, FALSE:Buffer overflow */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i, s;
|
int i, s;
|
||||||
WCHAR wc;
|
WCHAR wc, uc;
|
||||||
|
|
||||||
|
|
||||||
i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */
|
i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */
|
||||||
|
|
||||||
s = 0;
|
s = 0; wc = 1;
|
||||||
do {
|
do {
|
||||||
|
uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */
|
||||||
|
if (wc) { /* Last char has not been processed */
|
||||||
if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */
|
if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */
|
||||||
wc = LD_WORD(dir+LfnOfs[s]); /* Get an LFN char */
|
lfnbuf[i++] = wc = uc; /* Store it */
|
||||||
if (!wc) break; /* End of LFN? */
|
} else {
|
||||||
lfnbuf[i++] = wc; /* Store it */
|
if (uc != 0xFFFF) return FALSE; /* Check filler */
|
||||||
} while (++s < 13); /* Repeat until last char is copied */
|
}
|
||||||
|
} while (++s < 13); /* Read all character in the entry */
|
||||||
|
|
||||||
if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */
|
if (dir[LDIR_Ord] & 0x40) { /* Put terminator if it is the last LFN part */
|
||||||
if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */
|
if (i >= _MAX_LFN) return FALSE; /* Buffer overflow? */
|
||||||
|
@ -809,14 +834,14 @@ FRESULT dir_find (
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
BYTE c, *dir;
|
BYTE c, *dir;
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
BYTE a, lfen, ord, sum;
|
BYTE a, ord, sum;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
res = dir_seek(dj, 0); /* Rewind directory object */
|
res = dir_seek(dj, 0); /* Rewind directory object */
|
||||||
if (res != FR_OK) return res;
|
if (res != FR_OK) return res;
|
||||||
|
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
ord = sum = 0xFF; lfen = *(dj->fn+11) & NS_LOSS;
|
ord = sum = 0xFF;
|
||||||
#endif
|
#endif
|
||||||
do {
|
do {
|
||||||
res = move_window(dj->fs, dj->sect);
|
res = move_window(dj->fs, dj->sect);
|
||||||
|
@ -836,18 +861,13 @@ FRESULT dir_find (
|
||||||
c &= 0xBF; ord = c; /* LFN start order */
|
c &= 0xBF; ord = c; /* LFN start order */
|
||||||
dj->lfn_idx = dj->index;
|
dj->lfn_idx = dj->index;
|
||||||
}
|
}
|
||||||
/* Check LFN validity. Compare LFN if it is out of 8.3 format */
|
/* Check validity of the LFN entry and compare it with given name */
|
||||||
ord = (c == ord && sum == dir[LDIR_Chksum] && (!lfen || cmp_lfn(dj->lfn, dir))) ? ord - 1 : 0xFF;
|
ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
|
||||||
}
|
}
|
||||||
} else { /* An SFN entry is found */
|
} else { /* An SFN entry is found */
|
||||||
if (ord || sum != sum_sfn(dir)) /* Did not LFN match? */
|
if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */
|
||||||
dj->lfn_idx = 0xFFFF;
|
ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */
|
||||||
if (lfen) { /* Match LFN if it is out of 8.3 format */
|
if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */
|
||||||
if (ord == 0) break;
|
|
||||||
} else { /* Match SFN if LFN is in 8.3 format */
|
|
||||||
if (!mem_cmp(dir, dj->fn, 11)) break;
|
|
||||||
}
|
|
||||||
ord = 0xFF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* Non LFN configuration */
|
#else /* Non LFN configuration */
|
||||||
|
@ -899,8 +919,8 @@ FRESULT dir_read (
|
||||||
/* Check LFN validity and capture it */
|
/* Check LFN validity and capture it */
|
||||||
ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
|
ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;
|
||||||
} else { /* An SFN entry is found */
|
} else { /* An SFN entry is found */
|
||||||
if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN entry? */
|
if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */
|
||||||
dj->lfn_idx = 0xFFFF; /* No LFN. */
|
dj->lfn_idx = 0xFFFF; /* It has no LFN. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,10 +960,10 @@ FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many
|
||||||
fn = dj->fn; lfn = dj->lfn;
|
fn = dj->fn; lfn = dj->lfn;
|
||||||
mem_cpy(sn, fn, 12);
|
mem_cpy(sn, fn, 12);
|
||||||
|
|
||||||
if (_FS_RPATH && (sn[11] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */
|
if (_FS_RPATH && (sn[NS] & NS_DOT)) return FR_INVALID_NAME; /* Cannot create dot entry */
|
||||||
|
|
||||||
if (sn[11] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */
|
if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */
|
||||||
fn[11] = 0; dj->lfn = NULL; /* Find only SFN */
|
fn[NS] = 0; dj->lfn = NULL; /* Find only SFN */
|
||||||
for (n = 1; n < 100; n++) {
|
for (n = 1; n < 100; n++) {
|
||||||
gen_numname(fn, sn, lfn, n); /* Generate a numbered name */
|
gen_numname(fn, sn, lfn, n); /* Generate a numbered name */
|
||||||
res = dir_find(dj); /* Check if the name collides with existing SFN */
|
res = dir_find(dj); /* Check if the name collides with existing SFN */
|
||||||
|
@ -951,10 +971,10 @@ FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many
|
||||||
}
|
}
|
||||||
if (n == 100) return FR_DENIED; /* Abort if too many collisions */
|
if (n == 100) return FR_DENIED; /* Abort if too many collisions */
|
||||||
if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */
|
if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */
|
||||||
fn[11] = sn[11]; dj->lfn = lfn;
|
fn[NS] = sn[NS]; dj->lfn = lfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sn[11] & NS_LFN) { /* When LFN is to be created, reserve reserve an SFN + LFN entries. */
|
if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve reserve an SFN + LFN entries. */
|
||||||
for (ne = 0; lfn[ne]; ne++) ;
|
for (ne = 0; lfn[ne]; ne++) ;
|
||||||
ne = (ne + 25) / 13;
|
ne = (ne + 25) / 13;
|
||||||
} else { /* Otherwise reserve only an SFN entry. */
|
} else { /* Otherwise reserve only an SFN entry. */
|
||||||
|
@ -1012,7 +1032,7 @@ FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many
|
||||||
dir = dj->dir;
|
dir = dj->dir;
|
||||||
mem_set(dir, 0, 32); /* Clean the entry */
|
mem_set(dir, 0, 32); /* Clean the entry */
|
||||||
mem_cpy(dir, dj->fn, 11); /* Put SFN */
|
mem_cpy(dir, dj->fn, 11); /* Put SFN */
|
||||||
dir[DIR_NTres] = *(dj->fn+11) & 0x18; /* Put NT flag */
|
dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */
|
||||||
dj->fs->wflag = 1;
|
dj->fs->wflag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1073,7 +1093,6 @@ FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */
|
||||||
/* Pick a segment and create the object name in directory form */
|
/* Pick a segment and create the object name in directory form */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
FRESULT create_name (
|
FRESULT create_name (
|
||||||
DIR *dj, /* Pointer to the directory object */
|
DIR *dj, /* Pointer to the directory object */
|
||||||
|
@ -1083,6 +1102,7 @@ FRESULT create_name (
|
||||||
#ifdef _EXCVT
|
#ifdef _EXCVT
|
||||||
static const BYTE cvt[] = _EXCVT;
|
static const BYTE cvt[] = _EXCVT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _USE_LFN /* LFN configuration */
|
#if _USE_LFN /* LFN configuration */
|
||||||
BYTE b, cf;
|
BYTE b, cf;
|
||||||
WCHAR w, *lfn;
|
WCHAR w, *lfn;
|
||||||
|
@ -1095,29 +1115,29 @@ FRESULT create_name (
|
||||||
lfn = dj->lfn;
|
lfn = dj->lfn;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
w = p[si++]; /* Get a character */
|
w = p[si++]; /* Get a character */
|
||||||
if (w < L' ' || w == L'/' || w == L'\\') break; /* Break on end of segment */
|
if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */
|
||||||
if (di >= _MAX_LFN) /* Reject too long name */
|
if (di >= _MAX_LFN) /* Reject too long name */
|
||||||
return FR_INVALID_NAME;
|
return FR_INVALID_NAME;
|
||||||
#if !_LFN_UNICODE
|
#if !_LFN_UNICODE
|
||||||
w &= 0xFF;
|
w &= 0xFF;
|
||||||
if (IsDBCS1(w)) { /* If it is a DBC 1st byte */
|
if (IsDBCS1(w)) { /* If it is a DBC 1st byte */
|
||||||
BYTE c = p[si++]; /* Get 2nd byte */
|
b = p[si++]; /* Get 2nd byte */
|
||||||
if (!IsDBCS2(c)) /* Reject invalid code for DBC */
|
if (!IsDBCS2(b)) /* Reject invalid code for DBC */
|
||||||
return FR_INVALID_NAME;
|
return FR_INVALID_NAME;
|
||||||
w = (w << 8) + c;
|
w = (w << 8) + b;
|
||||||
}
|
}
|
||||||
w = ff_convert(w, 1); /* Convert OEM to Unicode */
|
w = ff_convert(w, 1); /* Convert OEM to Unicode */
|
||||||
if (!w) return FR_INVALID_NAME; /* Reject invalid code */
|
if (!w) return FR_INVALID_NAME; /* Reject invalid code */
|
||||||
#endif
|
#endif
|
||||||
if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject unallowable chars for LFN */
|
if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */
|
||||||
return FR_INVALID_NAME;
|
return FR_INVALID_NAME;
|
||||||
lfn[di++] = w; /* Store the Unicode char */
|
lfn[di++] = w; /* Store the Unicode char */
|
||||||
}
|
}
|
||||||
*path = &p[si]; /* Rerurn pointer to the next segment */
|
*path = &p[si]; /* Rerurn pointer to the next segment */
|
||||||
cf = (w < L' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
|
cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
|
||||||
#if _FS_RPATH
|
#if _FS_RPATH
|
||||||
if ((di == 1 && lfn[di - 1] == L'.') || /* Is this a dot entry? */
|
if ((di == 1 && lfn[di - 1] == '.') || /* Is this a dot entry? */
|
||||||
(di == 2 && lfn[di - 1] == L'.' && lfn[di - 2] == L'.')) {
|
(di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {
|
||||||
lfn[di] = 0;
|
lfn[di] = 0;
|
||||||
for (i = 0; i < 11; i++)
|
for (i = 0; i < 11; i++)
|
||||||
dj->fn[i] = (i < di) ? '.' : ' ';
|
dj->fn[i] = (i < di) ? '.' : ' ';
|
||||||
|
@ -1127,7 +1147,7 @@ FRESULT create_name (
|
||||||
#endif
|
#endif
|
||||||
while (di) { /* Strip trailing spaces and dots */
|
while (di) { /* Strip trailing spaces and dots */
|
||||||
w = lfn[di - 1];
|
w = lfn[di - 1];
|
||||||
if (w != L' ' && w != L'.') break;
|
if (w != ' ' && w != '.') break;
|
||||||
di--;
|
di--;
|
||||||
}
|
}
|
||||||
if (!di) return FR_INVALID_NAME; /* Reject null string */
|
if (!di) return FR_INVALID_NAME; /* Reject null string */
|
||||||
|
@ -1136,15 +1156,15 @@ FRESULT create_name (
|
||||||
|
|
||||||
/* Create SFN in directory form */
|
/* Create SFN in directory form */
|
||||||
mem_set(dj->fn, ' ', 11);
|
mem_set(dj->fn, ' ', 11);
|
||||||
for (si = 0; lfn[si] == L' ' || lfn[si] == L'.'; si++) ; /* Strip leading spaces and dots */
|
for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */
|
||||||
if (si) cf |= NS_LOSS | NS_LFN;
|
if (si) cf |= NS_LOSS | NS_LFN;
|
||||||
while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */
|
while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */
|
||||||
|
|
||||||
b = i = 0; ni = 8;
|
b = i = 0; ni = 8;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
w = lfn[si++]; /* Get an LFN char */
|
w = lfn[si++]; /* Get an LFN char */
|
||||||
if (!w) break; /* Break when enf of the LFN */
|
if (!w) break; /* Break on enf of the LFN */
|
||||||
if (w == L' ' || (w == L'.' && si != di)) { /* Remove spaces and dots */
|
if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */
|
||||||
cf |= NS_LOSS | NS_LFN; continue;
|
cf |= NS_LOSS | NS_LFN; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,7 +1172,7 @@ FRESULT create_name (
|
||||||
if (ni == 11) { /* Long extension */
|
if (ni == 11) { /* Long extension */
|
||||||
cf |= NS_LOSS | NS_LFN; break;
|
cf |= NS_LOSS | NS_LFN; break;
|
||||||
}
|
}
|
||||||
if (si != di) cf |= NS_LOSS | NS_LFN; /* File name is longer than 8 bytes */
|
if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */
|
||||||
if (si > di) break; /* No extension */
|
if (si > di) break; /* No extension */
|
||||||
si = di; i = 8; ni = 11; /* Enter extension section */
|
si = di; i = 8; ni = 11; /* Enter extension section */
|
||||||
b <<= 2; continue;
|
b <<= 2; continue;
|
||||||
|
@ -1161,11 +1181,11 @@ FRESULT create_name (
|
||||||
if (w >= 0x80) { /* Non ASCII char */
|
if (w >= 0x80) { /* Non ASCII char */
|
||||||
#ifdef _EXCVT
|
#ifdef _EXCVT
|
||||||
w = ff_convert(w, 0); /* Unicode -> OEM code */
|
w = ff_convert(w, 0); /* Unicode -> OEM code */
|
||||||
if (w) w = cvt[w - 0x80]; /* Convert extend char (SBCS) */
|
if (w) w = cvt[w - 0x80]; /* Convert extended char to upper (SBCS) */
|
||||||
#else
|
#else
|
||||||
w = ff_convert(ff_wtoupper(w), 0); /* Unicode (Caps) -> OEM code */
|
w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */
|
||||||
#endif
|
#endif
|
||||||
cf |= NS_LFN; /* Force create an LFN */
|
cf |= NS_LFN; /* Force create LFN entry */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_DF1S && w >= 0x100) { /* Double byte char */
|
if (_DF1S && w >= 0x100) { /* Double byte char */
|
||||||
|
@ -1174,13 +1194,13 @@ FRESULT create_name (
|
||||||
}
|
}
|
||||||
dj->fn[i++] = (BYTE)(w >> 8);
|
dj->fn[i++] = (BYTE)(w >> 8);
|
||||||
} else { /* Single byte char */
|
} else { /* Single byte char */
|
||||||
if (!w || chk_chr("+,;[=]", w)) { /* Replace unallowable chars for SFN */
|
if (!w || chk_chr("+,;[=]", w)) { /* Replace illegal chars for SFN */
|
||||||
w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */
|
w = '_'; cf |= NS_LOSS | NS_LFN; /* Lossy conversion */
|
||||||
} else {
|
} else {
|
||||||
if (IsUpper(w)) { /* Large capital */
|
if (IsUpper(w)) { /* ASCII large capital */
|
||||||
b |= 2;
|
b |= 2;
|
||||||
} else {
|
} else {
|
||||||
if (IsLower(w)) { /* Small capital */
|
if (IsLower(w)) { /* ASCII small capital */
|
||||||
b |= 1; w -= 0x20;
|
b |= 1; w -= 0x20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1209,7 @@ FRESULT create_name (
|
||||||
dj->fn[i++] = (BYTE)w;
|
dj->fn[i++] = (BYTE)w;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with 0xE5, replace it with 0x05 */
|
if (dj->fn[0] == 0xE5) dj->fn[0] = 0x05; /* If the first char collides with deleted mark, replace it with 0x05 */
|
||||||
|
|
||||||
if (ni == 8) b <<= 2;
|
if (ni == 8) b <<= 2;
|
||||||
if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */
|
if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */
|
||||||
|
@ -1199,7 +1219,9 @@ FRESULT create_name (
|
||||||
if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */
|
if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */
|
||||||
}
|
}
|
||||||
|
|
||||||
dj->fn[11] = cf; /* SFN is created */
|
dj->fn[NS] = cf; /* SFN is created */
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
|
||||||
|
|
||||||
#else /* Non-LFN configuration */
|
#else /* Non-LFN configuration */
|
||||||
|
@ -1219,15 +1241,15 @@ FRESULT create_name (
|
||||||
if (c != '.' || si >= 3) break;
|
if (c != '.' || si >= 3) break;
|
||||||
sfn[i++] = c;
|
sfn[i++] = c;
|
||||||
}
|
}
|
||||||
if (c != '/' && c != '\\' && c >= ' ') return FR_INVALID_NAME;
|
if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;
|
||||||
*path = &p[si]; /* Rerurn pointer to the next segment */
|
*path = &p[si]; /* Rerurn pointer to the next segment */
|
||||||
sfn[11] = (c < ' ') ? NS_LAST|NS_DOT : NS_DOT; /* Set last segment flag if end of path */
|
sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */
|
||||||
return FR_OK;
|
return FR_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = p[si++];
|
c = p[si++];
|
||||||
if (c < ' ' || c == '/' || c == '\\') break; /* Break on end of segment */
|
if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */
|
||||||
if (c == '.' || i >= ni) {
|
if (c == '.' || i >= ni) {
|
||||||
if (ni != 8 || c != '.') return FR_INVALID_NAME;
|
if (ni != 8 || c != '.') return FR_INVALID_NAME;
|
||||||
i = 8; ni = 11;
|
i = 8; ni = 11;
|
||||||
|
@ -1243,19 +1265,19 @@ FRESULT create_name (
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (IsDBCS1(c)) { /* If it is DBC 1st byte */
|
if (IsDBCS1(c)) { /* DBC 1st byte? */
|
||||||
d = p[si++]; /* Get 2nd byte */
|
d = p[si++]; /* Get 2nd byte */
|
||||||
if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */
|
if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */
|
||||||
return FR_INVALID_NAME;
|
return FR_INVALID_NAME;
|
||||||
sfn[i++] = c;
|
sfn[i++] = c;
|
||||||
sfn[i++] = d;
|
sfn[i++] = d;
|
||||||
} else {
|
} else { /* Single byte code */
|
||||||
if (chk_chr(" \"*+,[=]|\x7F", c)) /* Reject unallowable chrs for SFN */
|
if (chk_chr(" \"*+,[=]|\x7F", c)) /* Reject illegal chrs for SFN */
|
||||||
return FR_INVALID_NAME;
|
return FR_INVALID_NAME;
|
||||||
if (IsUpper(c)) {
|
if (IsUpper(c)) { /* ASCII large capital? */
|
||||||
b |= 2;
|
b |= 2;
|
||||||
} else {
|
} else {
|
||||||
if (IsLower(c)) {
|
if (IsLower(c)) { /* ASCII small capital? */
|
||||||
b |= 1; c -= 0x20;
|
b |= 1; c -= 0x20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1263,7 +1285,7 @@ FRESULT create_name (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*path = &p[si]; /* Rerurn pointer to the next segment */
|
*path = &p[si]; /* Rerurn pointer to the next segment */
|
||||||
c = (c < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
|
c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */
|
||||||
|
|
||||||
if (!i) return FR_INVALID_NAME; /* Reject null string */
|
if (!i) return FR_INVALID_NAME; /* Reject null string */
|
||||||
if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */
|
if (sfn[0] == 0xE5) sfn[0] = 0x05; /* When first char collides with 0xE5, replace it with 0x05 */
|
||||||
|
@ -1272,10 +1294,10 @@ FRESULT create_name (
|
||||||
if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Extension has only small capital) */
|
if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Extension has only small capital) */
|
||||||
if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Filename has only small capital) */
|
if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Filename has only small capital) */
|
||||||
|
|
||||||
sfn[11] = c; /* Store NT flag, File name is created */
|
sfn[NS] = c; /* Store NT flag, File name is created */
|
||||||
#endif
|
|
||||||
|
|
||||||
return FR_OK;
|
return FR_OK;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1288,15 +1310,12 @@ FRESULT create_name (
|
||||||
static
|
static
|
||||||
void get_fileinfo ( /* No return code */
|
void get_fileinfo ( /* No return code */
|
||||||
DIR *dj, /* Pointer to the directory object */
|
DIR *dj, /* Pointer to the directory object */
|
||||||
FILINFO *fno /* Pointer to store the file information */
|
FILINFO *fno /* Pointer to the file information to be filled */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
BYTE c, nt, *dir;
|
BYTE c, nt, *dir;
|
||||||
char *p;
|
char *p;
|
||||||
#if _USE_LFN
|
|
||||||
XCHAR *tp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
p = fno->fname;
|
p = fno->fname;
|
||||||
|
@ -1307,7 +1326,7 @@ void get_fileinfo ( /* No return code */
|
||||||
c = dir[i];
|
c = dir[i];
|
||||||
if (c == ' ') break;
|
if (c == ' ') break;
|
||||||
if (c == 0x05) c = 0xE5;
|
if (c == 0x05) c = 0xE5;
|
||||||
if ((nt & 0x08) && IsUpper(c)) c += 0x20;
|
if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20;
|
||||||
*p++ = c;
|
*p++ = c;
|
||||||
}
|
}
|
||||||
if (dir[8] != ' ') { /* Copy name extension */
|
if (dir[8] != ' ') { /* Copy name extension */
|
||||||
|
@ -1315,7 +1334,7 @@ void get_fileinfo ( /* No return code */
|
||||||
for (i = 8; i < 11; i++) {
|
for (i = 8; i < 11; i++) {
|
||||||
c = dir[i];
|
c = dir[i];
|
||||||
if (c == ' ') break;
|
if (c == ' ') break;
|
||||||
if ((nt & 0x10) && IsUpper(c)) c += 0x20;
|
if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20;
|
||||||
*p++ = c;
|
*p++ = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1327,8 +1346,8 @@ void get_fileinfo ( /* No return code */
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
tp = fno->lfname;
|
if (fno->lfname) {
|
||||||
if (tp) {
|
XCHAR *tp = fno->lfname;
|
||||||
WCHAR w, *lfn;
|
WCHAR w, *lfn;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1340,8 +1359,8 @@ void get_fileinfo ( /* No return code */
|
||||||
if (!w) { i = 0; break; } /* Could not convert, no LFN */
|
if (!w) { i = 0; break; } /* Could not convert, no LFN */
|
||||||
if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */
|
if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC */
|
||||||
tp[i++] = (XCHAR)(w >> 8);
|
tp[i++] = (XCHAR)(w >> 8);
|
||||||
if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */
|
|
||||||
#endif
|
#endif
|
||||||
|
if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overrun, no LFN */
|
||||||
tp[i++] = (XCHAR)w;
|
tp[i++] = (XCHAR)w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1368,6 +1387,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
|
||||||
BYTE *dir, last;
|
BYTE *dir, last;
|
||||||
|
|
||||||
|
|
||||||
|
while (!_USE_LFN && *path == ' ') path++; /* Skip leading spaces */
|
||||||
#if _FS_RPATH
|
#if _FS_RPATH
|
||||||
if (*path == '/' || *path == '\\') { /* There is a heading separator */
|
if (*path == '/' || *path == '\\') { /* There is a heading separator */
|
||||||
path++; dj->sclust = 0; /* Strip it and start from the root dir */
|
path++; dj->sclust = 0; /* Strip it and start from the root dir */
|
||||||
|
@ -1389,7 +1409,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
|
||||||
res = create_name(dj, &path); /* Get a segment */
|
res = create_name(dj, &path); /* Get a segment */
|
||||||
if (res != FR_OK) break;
|
if (res != FR_OK) break;
|
||||||
res = dir_find(dj); /* Find it */
|
res = dir_find(dj); /* Find it */
|
||||||
last = *(dj->fn+11) & NS_LAST;
|
last = *(dj->fn+NS) & NS_LAST;
|
||||||
if (res != FR_OK) { /* Could not find the object */
|
if (res != FR_OK) { /* Could not find the object */
|
||||||
if (res == FR_NO_FILE && !last)
|
if (res == FR_NO_FILE && !last)
|
||||||
res = FR_NO_PATH;
|
res = FR_NO_PATH;
|
||||||
|
@ -1420,17 +1440,14 @@ BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:
|
||||||
DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
|
DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static const char fatstr[] = "FAT";
|
|
||||||
|
|
||||||
|
|
||||||
if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK) /* Load boot record */
|
if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK) /* Load boot record */
|
||||||
return 3;
|
return 3;
|
||||||
if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */
|
if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
if (!mem_cmp(&fs->win[BS_FilSysType], fatstr, 3)) /* Check FAT signature */
|
if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */
|
||||||
return 0;
|
return 0;
|
||||||
if (!mem_cmp(&fs->win[BS_FilSysType32], fatstr, 3) && !(fs->win[BPB_ExtFlags] & 0x80))
|
if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1443,14 +1460,13 @@ BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:
|
||||||
/* Make sure that the file system is valid */
|
/* Make sure that the file system is valid */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
static
|
|
||||||
FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */
|
FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occured */
|
||||||
const XCHAR **path, /* Pointer to pointer to the path name (drive number) */
|
const XCHAR **path, /* Pointer to pointer to the path name (drive number) */
|
||||||
FATFS **rfs, /* Pointer to pointer to the found file system object */
|
FATFS **rfs, /* Pointer to pointer to the found file system object */
|
||||||
BYTE chk_wp /* !=0: Check media write protection for write access */
|
BYTE chk_wp /* !=0: Check media write protection for write access */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FRESULT res;
|
|
||||||
BYTE fmt, *tbl;
|
BYTE fmt, *tbl;
|
||||||
UINT vol;
|
UINT vol;
|
||||||
DSTATUS stat;
|
DSTATUS stat;
|
||||||
|
@ -1458,7 +1474,6 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */
|
||||||
const XCHAR *p = *path;
|
const XCHAR *p = *path;
|
||||||
FATFS *fs;
|
FATFS *fs;
|
||||||
|
|
||||||
|
|
||||||
/* Get logical drive number from the path name */
|
/* Get logical drive number from the path name */
|
||||||
vol = p[0] - '0'; /* Is there a drive number? */
|
vol = p[0] - '0'; /* Is there a drive number? */
|
||||||
if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */
|
if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */
|
||||||
|
@ -1475,7 +1490,7 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */
|
||||||
if (vol >= _DRIVES) /* Is the drive number valid? */
|
if (vol >= _DRIVES) /* Is the drive number valid? */
|
||||||
return FR_INVALID_DRIVE;
|
return FR_INVALID_DRIVE;
|
||||||
*rfs = fs = FatFs[vol]; /* Returen pointer to the corresponding file system object */
|
*rfs = fs = FatFs[vol]; /* Returen pointer to the corresponding file system object */
|
||||||
if (!fs) return FR_NOT_ENABLED; /* Is the file system object registered? */
|
if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */
|
||||||
|
|
||||||
ENTER_FF(fs); /* Lock file system */
|
ENTER_FF(fs); /* Lock file system */
|
||||||
|
|
||||||
|
@ -1528,9 +1543,9 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */
|
||||||
fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */
|
fs->fatbase = bsect + LD_WORD(fs->win+BPB_RsvdSecCnt); /* FAT start sector (lba) */
|
||||||
fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */
|
fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */
|
||||||
fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Nmuber of root directory entries */
|
fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Nmuber of root directory entries */
|
||||||
tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the file system */
|
tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */
|
||||||
if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
|
if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
|
||||||
fs->max_clust = mclst = (tsect /* Last cluster# + 1 */
|
fs->max_clust = mclst = (tsect /* Last cluster# + 1 (Number of clusters + 2) */
|
||||||
- LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32)
|
- LD_WORD(fs->win+BPB_RsvdSecCnt) - fsize - fs->n_rootdir / (SS(fs)/32)
|
||||||
) / fs->csize + 2;
|
) / fs->csize + 2;
|
||||||
|
|
||||||
|
@ -1567,9 +1582,8 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */
|
||||||
fs->cdir = 0; /* Current directory (root dir) */
|
fs->cdir = 0; /* Current directory (root dir) */
|
||||||
#endif
|
#endif
|
||||||
fs->id = ++Fsid; /* File system mount ID */
|
fs->id = ++Fsid; /* File system mount ID */
|
||||||
res = FR_OK;
|
|
||||||
|
|
||||||
return res;
|
return FR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1663,10 +1677,10 @@ FRESULT f_open (
|
||||||
fp->fs = NULL; /* Clear file object */
|
fp->fs = NULL; /* Clear file object */
|
||||||
#if !_FS_READONLY
|
#if !_FS_READONLY
|
||||||
mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW);
|
mode &= (FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW);
|
||||||
res = auto_mount(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)));
|
res = chk_mounted(&path, &dj.fs, (BYTE)(mode & (FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)));
|
||||||
#else
|
#else
|
||||||
mode &= FA_READ;
|
mode &= FA_READ;
|
||||||
res = auto_mount(&path, &dj.fs, 0);
|
res = chk_mounted(&path, &dj.fs, 0);
|
||||||
#endif
|
#endif
|
||||||
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
|
@ -1759,7 +1773,7 @@ FRESULT f_read (
|
||||||
BYTE *rbuff = buff;
|
BYTE *rbuff = buff;
|
||||||
|
|
||||||
|
|
||||||
*br = 0;
|
*br = 0; /* Initialize bytes read */
|
||||||
|
|
||||||
res = validate(fp->fs, fp->id); /* Check validity of the object */
|
res = validate(fp->fs, fp->id); /* Check validity of the object */
|
||||||
if (res != FR_OK) LEAVE_FF(fp->fs, res);
|
if (res != FR_OK) LEAVE_FF(fp->fs, res);
|
||||||
|
@ -1854,7 +1868,7 @@ FRESULT f_write (
|
||||||
const BYTE *wbuff = buff;
|
const BYTE *wbuff = buff;
|
||||||
|
|
||||||
|
|
||||||
*bw = 0;
|
*bw = 0; /* Initialize bytes written */
|
||||||
|
|
||||||
res = validate(fp->fs, fp->id); /* Check validity of the object */
|
res = validate(fp->fs, fp->id); /* Check validity of the object */
|
||||||
if (res != FR_OK) LEAVE_FF(fp->fs, res);
|
if (res != FR_OK) LEAVE_FF(fp->fs, res);
|
||||||
|
@ -2055,7 +2069,7 @@ FRESULT f_chdir (
|
||||||
BYTE *dir;
|
BYTE *dir;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 0);
|
res = chk_mounted(&path, &dj.fs, 0);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
|
@ -2194,7 +2208,7 @@ FRESULT f_opendir (
|
||||||
BYTE *dir;
|
BYTE *dir;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj->fs, 0);
|
res = chk_mounted(&path, &dj->fs, 0);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
INITBUF((*dj), sfn, lfn);
|
INITBUF((*dj), sfn, lfn);
|
||||||
res = follow_path(dj, path); /* Follow the path to the directory */
|
res = follow_path(dj, path); /* Follow the path to the directory */
|
||||||
|
@ -2276,7 +2290,7 @@ FRESULT f_stat (
|
||||||
NAMEBUF(sfn, lfn);
|
NAMEBUF(sfn, lfn);
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 0);
|
res = chk_mounted(&path, &dj.fs, 0);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
|
@ -2311,7 +2325,7 @@ FRESULT f_getfree (
|
||||||
|
|
||||||
|
|
||||||
/* Get drive number */
|
/* Get drive number */
|
||||||
res = auto_mount(&path, fatfs, 0);
|
res = chk_mounted(&path, fatfs, 0);
|
||||||
if (res != FR_OK) LEAVE_FF(*fatfs, res);
|
if (res != FR_OK) LEAVE_FF(*fatfs, res);
|
||||||
|
|
||||||
/* If number of free cluster is valid, return it without cluster scan. */
|
/* If number of free cluster is valid, return it without cluster scan. */
|
||||||
|
@ -2347,7 +2361,7 @@ FRESULT f_getfree (
|
||||||
if (LD_WORD(p) == 0) n++;
|
if (LD_WORD(p) == 0) n++;
|
||||||
p += 2; i -= 2;
|
p += 2; i -= 2;
|
||||||
} else {
|
} else {
|
||||||
if (LD_DWORD(p) == 0) n++;
|
if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
|
||||||
p += 4; i -= 4;
|
p += 4; i -= 4;
|
||||||
}
|
}
|
||||||
} while (--clst);
|
} while (--clst);
|
||||||
|
@ -2421,12 +2435,12 @@ FRESULT f_unlink (
|
||||||
DWORD dclst;
|
DWORD dclst;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 1);
|
res = chk_mounted(&path, &dj.fs, 1);
|
||||||
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
||||||
|
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
if (_FS_RPATH && res == FR_OK && (dj.fn[11] & NS_DOT))
|
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
|
||||||
res = FR_INVALID_NAME;
|
res = FR_INVALID_NAME;
|
||||||
if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */
|
if (res != FR_OK) LEAVE_FF(dj.fs, res); /* Follow failed */
|
||||||
|
|
||||||
|
@ -2441,7 +2455,7 @@ FRESULT f_unlink (
|
||||||
if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR);
|
if (dclst < 2) LEAVE_FF(dj.fs, FR_INT_ERR);
|
||||||
mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */
|
mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */
|
||||||
sdj.sclust = dclst;
|
sdj.sclust = dclst;
|
||||||
res = dir_seek(&sdj, 0);
|
res = dir_seek(&sdj, 2);
|
||||||
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
||||||
res = dir_read(&sdj);
|
res = dir_read(&sdj);
|
||||||
if (res == FR_OK) res = FR_DENIED; /* Not empty sub-dir */
|
if (res == FR_OK) res = FR_DENIED; /* Not empty sub-dir */
|
||||||
|
@ -2476,13 +2490,13 @@ FRESULT f_mkdir (
|
||||||
DWORD dsect, dclst, pclst, tim;
|
DWORD dsect, dclst, pclst, tim;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 1);
|
res = chk_mounted(&path, &dj.fs, 1);
|
||||||
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
if (res != FR_OK) LEAVE_FF(dj.fs, res);
|
||||||
|
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
if (res == FR_OK) res = FR_EXIST; /* Any file or directory is already existing */
|
if (res == FR_OK) res = FR_EXIST; /* Any file or directory is already existing */
|
||||||
if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[11] & NS_DOT))
|
if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))
|
||||||
res = FR_INVALID_NAME;
|
res = FR_INVALID_NAME;
|
||||||
if (res != FR_NO_FILE) /* Any error occured */
|
if (res != FR_NO_FILE) /* Any error occured */
|
||||||
LEAVE_FF(dj.fs, res);
|
LEAVE_FF(dj.fs, res);
|
||||||
|
@ -2556,11 +2570,11 @@ FRESULT f_chmod (
|
||||||
BYTE *dir;
|
BYTE *dir;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 1);
|
res = chk_mounted(&path, &dj.fs, 1);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
if (_FS_RPATH && res == FR_OK && (dj.fn[11] & NS_DOT))
|
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
|
||||||
res = FR_INVALID_NAME;
|
res = FR_INVALID_NAME;
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
dir = dj.dir;
|
dir = dj.dir;
|
||||||
|
@ -2596,11 +2610,11 @@ FRESULT f_utime (
|
||||||
BYTE *dir;
|
BYTE *dir;
|
||||||
|
|
||||||
|
|
||||||
res = auto_mount(&path, &dj.fs, 1);
|
res = chk_mounted(&path, &dj.fs, 1);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
INITBUF(dj, sfn, lfn);
|
INITBUF(dj, sfn, lfn);
|
||||||
res = follow_path(&dj, path); /* Follow the file path */
|
res = follow_path(&dj, path); /* Follow the file path */
|
||||||
if (_FS_RPATH && res == FR_OK && (dj.fn[11] & NS_DOT))
|
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
|
||||||
res = FR_INVALID_NAME;
|
res = FR_INVALID_NAME;
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
dir = dj.dir;
|
dir = dj.dir;
|
||||||
|
@ -2638,11 +2652,11 @@ FRESULT f_rename (
|
||||||
|
|
||||||
|
|
||||||
INITBUF(dj_old, sfn, lfn);
|
INITBUF(dj_old, sfn, lfn);
|
||||||
res = auto_mount(&path_old, &dj_old.fs, 1);
|
res = chk_mounted(&path_old, &dj_old.fs, 1);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
dj_new.fs = dj_old.fs;
|
dj_new.fs = dj_old.fs;
|
||||||
res = follow_path(&dj_old, path_old); /* Check old object */
|
res = follow_path(&dj_old, path_old); /* Check old object */
|
||||||
if (_FS_RPATH && res == FR_OK && (dj_old.fn[11] & NS_DOT))
|
if (_FS_RPATH && res == FR_OK && (dj_old.fn[NS] & NS_DOT))
|
||||||
res = FR_INVALID_NAME;
|
res = FR_INVALID_NAME;
|
||||||
}
|
}
|
||||||
if (res != FR_OK) LEAVE_FF(dj_old.fs, res); /* The old object is not found */
|
if (res != FR_OK) LEAVE_FF(dj_old.fs, res); /* The old object is not found */
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*---------------------------------------------------------------------------/
|
/*---------------------------------------------------------------------------/
|
||||||
/ FatFs - FAT file system module include file R0.07c (C)ChaN, 2009
|
/ FatFs - FAT file system module include file R0.07e (C)ChaN, 2009
|
||||||
/----------------------------------------------------------------------------/
|
/----------------------------------------------------------------------------/
|
||||||
/ FatFs module is an open source software to implement FAT file system to
|
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||||
/ small embedded systems. This is a free software and is opened for education,
|
/ This is a free software that opened for education, research and commercial
|
||||||
/ research and commercial developments under license policy of following trems.
|
/ developments under license policy of following trems.
|
||||||
/
|
/
|
||||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||||
/
|
/
|
||||||
|
@ -13,150 +13,17 @@
|
||||||
/ * Redistributions of source code must retain the above copyright notice.
|
/ * Redistributions of source code must retain the above copyright notice.
|
||||||
/----------------------------------------------------------------------------*/
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "integer.h"
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ FatFs Configuration Options
|
|
||||||
/
|
|
||||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
|
||||||
/ the configuration options.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
#ifndef _FATFS
|
#ifndef _FATFS
|
||||||
#define _FATFS 0x007C
|
#define _FATFS 0x007E
|
||||||
|
|
||||||
#ifdef RT_DFS_ELM_WORD_ACCESS
|
#include <rtthread.h>
|
||||||
#define _WORD_ACCESS 1
|
#include "integer.h" /* Basic integer types */
|
||||||
#else
|
#include "ffconf.h" /* FatFs configuration options */
|
||||||
#define _WORD_ACCESS 0
|
|
||||||
|
#if _FATFS != _FFCONFIG
|
||||||
|
#error Wrong configuration file (ffconf.h).
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The _WORD_ACCESS option defines which access method is used to the word
|
|
||||||
/ data in the FAT structure.
|
|
||||||
/
|
|
||||||
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
|
||||||
/ 1: Word access. Do not choose this unless following condition is met.
|
|
||||||
/
|
|
||||||
/ When the byte order on the memory is big-endian or address miss-aligned
|
|
||||||
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
|
||||||
/ If it is not the case, the value can also be set to 1 to improve the
|
|
||||||
/ performance and code efficiency. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_READONLY 0
|
|
||||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
|
||||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
|
||||||
/ f_truncate and useless f_getfree. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_MINIMIZE 0
|
|
||||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
|
||||||
/
|
|
||||||
/ 0: Full function.
|
|
||||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
|
||||||
/ are removed.
|
|
||||||
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
|
||||||
/ 3: f_lseek is removed in addition to level 2. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_TINY 0
|
|
||||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
|
||||||
/ object instead of the sector buffer in the individual file object for file
|
|
||||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_STRFUNC 0
|
|
||||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_MKFS 0
|
|
||||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_FORWARD 0
|
|
||||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _CODE_PAGE 936
|
|
||||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
|
||||||
/
|
|
||||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
|
||||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
|
||||||
/ 949 - Korean (DBCS, OEM, Windows)
|
|
||||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
|
||||||
/ 1250 - Central Europe (Windows)
|
|
||||||
/ 1251 - Cyrillic (Windows)
|
|
||||||
/ 1252 - Latin 1 (Windows)
|
|
||||||
/ 1253 - Greek (Windows)
|
|
||||||
/ 1254 - Turkish (Windows)
|
|
||||||
/ 1255 - Hebrew (Windows)
|
|
||||||
/ 1256 - Arabic (Windows)
|
|
||||||
/ 1257 - Baltic (Windows)
|
|
||||||
/ 1258 - Vietnam (OEM, Windows)
|
|
||||||
/ 437 - U.S. (OEM)
|
|
||||||
/ 720 - Arabic (OEM)
|
|
||||||
/ 737 - Greek (OEM)
|
|
||||||
/ 775 - Baltic (OEM)
|
|
||||||
/ 850 - Multilingual Latin 1 (OEM)
|
|
||||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
|
||||||
/ 852 - Latin 2 (OEM)
|
|
||||||
/ 855 - Cyrillic (OEM)
|
|
||||||
/ 866 - Russian (OEM)
|
|
||||||
/ 857 - Turkish (OEM)
|
|
||||||
/ 862 - Hebrew (OEM)
|
|
||||||
/ 874 - Thai (OEM, Windows)
|
|
||||||
/ 1 - ASCII (Valid for only non LFN cfg.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_LFN 0
|
|
||||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
|
||||||
/* The _USE_LFN option switches the LFN support.
|
|
||||||
/
|
|
||||||
/ 0: Disable LFN.
|
|
||||||
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
|
||||||
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
|
||||||
/
|
|
||||||
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
|
||||||
/ a Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
|
||||||
/ to the project. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_RPATH 0
|
|
||||||
/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,
|
|
||||||
/ f_chdrive function are available.
|
|
||||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_REENTRANT 0
|
|
||||||
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks of the OS */
|
|
||||||
#define _SYNC_t HANDLE /* Type of sync object used on the OS. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
|
||||||
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
|
||||||
/ provided synchronization handlers, ff_req_grant, ff_rel_grant, ff_del_syncobj
|
|
||||||
/ and ff_cre_syncobj function to the project. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _DRIVES 1
|
|
||||||
/* Number of volumes (logical drives) to be used. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _MAX_SS 512
|
|
||||||
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
|
||||||
/* Usually set 512 for memory card and hard disk but 1024 for floppy disk, 2048 for MO disk */
|
|
||||||
/* When _MAX_SS > 512, GET_SECTOR_SIZE must be implememted to disk_ioctl() */
|
|
||||||
|
|
||||||
|
|
||||||
#define _MULTI_PARTITION 0
|
|
||||||
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
|
||||||
/ drive number and can mount only first primaly partition. When it is set to 1,
|
|
||||||
/ each volume is tied to the partitions listed in Drives[]. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of configuration options. Do not change followings without care. */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* DBCS code ranges and SBCS extend char conversion table */
|
/* DBCS code ranges and SBCS extend char conversion table */
|
||||||
|
|
||||||
|
@ -357,17 +224,16 @@
|
||||||
|
|
||||||
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||||
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||||
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
|
||||||
|
|
||||||
#if _DF1S /* DBCS configuration */
|
#if _DF1S /* DBCS configuration */
|
||||||
|
|
||||||
#if _DF2S /* Two 1st byte areas */
|
#ifdef _DF2S /* Two 1st byte areas */
|
||||||
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||||
#else /* One 1st byte area */
|
#else /* One 1st byte area */
|
||||||
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _DS3S /* Three 2nd byte areas */
|
#ifdef _DS3S /* Three 2nd byte areas */
|
||||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||||
#else /* Two 2nd byte areas */
|
#else /* Two 2nd byte areas */
|
||||||
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||||
|
@ -407,10 +273,10 @@ const PARTITION Drives[]; /* Logical drive# to physical location conversion ta
|
||||||
|
|
||||||
/* Definitions corresponds to multiple sector size */
|
/* Definitions corresponds to multiple sector size */
|
||||||
|
|
||||||
#if _MAX_SS == 512
|
#if _MAX_SS == 512 /* Single sector size */
|
||||||
#define SS(fs) 512U
|
#define SS(fs) 512U
|
||||||
|
|
||||||
#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
#elif _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096 /* Multiple sector size */
|
||||||
#define SS(fs) ((fs)->s_size)
|
#define SS(fs) ((fs)->s_size)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -438,6 +304,7 @@ typedef struct _FATFS_ {
|
||||||
BYTE csize; /* Number of sectors per cluster */
|
BYTE csize; /* Number of sectors per cluster */
|
||||||
BYTE n_fats; /* Number of FAT copies */
|
BYTE n_fats; /* Number of FAT copies */
|
||||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||||
|
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||||
WORD id; /* File system mount ID */
|
WORD id; /* File system mount ID */
|
||||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||||
#if _FS_REENTRANT
|
#if _FS_REENTRANT
|
||||||
|
@ -447,7 +314,6 @@ typedef struct _FATFS_ {
|
||||||
WORD s_size; /* Sector size */
|
WORD s_size; /* Sector size */
|
||||||
#endif
|
#endif
|
||||||
#if !_FS_READONLY
|
#if !_FS_READONLY
|
||||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
|
||||||
DWORD last_clust; /* Last allocated cluster */
|
DWORD last_clust; /* Last allocated cluster */
|
||||||
DWORD free_clust; /* Number of free clusters */
|
DWORD free_clust; /* Number of free clusters */
|
||||||
DWORD fsi_sector; /* fsinfo sector */
|
DWORD fsi_sector; /* fsinfo sector */
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ FatFs - FAT file system module configuration file R0.07e (C)ChaN, 2009
|
||||||
|
/----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||||
|
/ the configuration options.
|
||||||
|
/
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
#ifndef _FFCONFIG
|
||||||
|
#define _FFCONFIG 0x007E
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Function and Buffer Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _FS_TINY 0 /* 0 or 1 */
|
||||||
|
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||||
|
/ object instead of the sector buffer in the individual file object for file
|
||||||
|
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_READONLY 0 /* 0 or 1 */
|
||||||
|
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||||
|
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||||
|
/ f_truncate and useless f_getfree. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */
|
||||||
|
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||||
|
/
|
||||||
|
/ 0: Full function.
|
||||||
|
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||||
|
/ 3: f_lseek is removed in addition to level 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_STRFUNC 0 /* 0, 1 or 2 */
|
||||||
|
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_MKFS 0 /* 0 or 1 */
|
||||||
|
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_FORWARD 0 /* 0 or 1 */
|
||||||
|
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _CODE_PAGE 936
|
||||||
|
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect setting of the code page can cause a file open failure.
|
||||||
|
/
|
||||||
|
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||||
|
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||||
|
/ 949 - Korean (DBCS, OEM, Windows)
|
||||||
|
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||||
|
/ 1250 - Central Europe (Windows)
|
||||||
|
/ 1251 - Cyrillic (Windows)
|
||||||
|
/ 1252 - Latin 1 (Windows)
|
||||||
|
/ 1253 - Greek (Windows)
|
||||||
|
/ 1254 - Turkish (Windows)
|
||||||
|
/ 1255 - Hebrew (Windows)
|
||||||
|
/ 1256 - Arabic (Windows)
|
||||||
|
/ 1257 - Baltic (Windows)
|
||||||
|
/ 1258 - Vietnam (OEM, Windows)
|
||||||
|
/ 437 - U.S. (OEM)
|
||||||
|
/ 720 - Arabic (OEM)
|
||||||
|
/ 737 - Greek (OEM)
|
||||||
|
/ 775 - Baltic (OEM)
|
||||||
|
/ 850 - Multilingual Latin 1 (OEM)
|
||||||
|
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||||
|
/ 852 - Latin 2 (OEM)
|
||||||
|
/ 855 - Cyrillic (OEM)
|
||||||
|
/ 866 - Russian (OEM)
|
||||||
|
/ 857 - Turkish (OEM)
|
||||||
|
/ 862 - Hebrew (OEM)
|
||||||
|
/ 874 - Thai (OEM, Windows)
|
||||||
|
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_LFN 0 /* 0, 1 or 2 */
|
||||||
|
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||||
|
/* The _USE_LFN option switches the LFN support.
|
||||||
|
/
|
||||||
|
/ 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||||
|
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||||
|
/
|
||||||
|
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||||
|
/ two Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||||
|
/ to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _LFN_UNICODE 0 /* 0 or 1 */
|
||||||
|
/* To switch the character code set on FatFs API to Unicode,
|
||||||
|
/ enable LFN feature and set _LFN_UNICODE to 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_RPATH 0 /* 0 or 1 */
|
||||||
|
/* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir,
|
||||||
|
/ f_chdrive function are available.
|
||||||
|
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Physical Drive Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define _DRIVES 1
|
||||||
|
/* Number of volumes (logical drives) to be used. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||||
|
/* Maximum sector size to be handled.
|
||||||
|
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||||
|
/ required for floppy disk (512/1024) and optical disk (512/2048).
|
||||||
|
/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
|
||||||
|
/ to the disk_ioctl function. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MULTI_PARTITION 0 /* 0 or 1 */
|
||||||
|
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||||
|
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||||
|
/ each volume is tied to the partitions listed in Drives[]. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ System Configurations
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
#ifdef RT_DFS_ELM_WORD_ACCESS
|
||||||
|
#define _WORD_ACCESS 1
|
||||||
|
#else
|
||||||
|
#define _WORD_ACCESS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||||
|
/ data on the FAT volume.
|
||||||
|
/
|
||||||
|
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||||
|
/ 1: Word access. Do not choose this unless following condition is met.
|
||||||
|
/
|
||||||
|
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||||
|
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||||
|
/ If it is not the case, the value can also be set to 1 to improve the
|
||||||
|
/ performance and code size. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_REENTRANT 0 /* 0 or 1 */
|
||||||
|
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||||
|
#define _SYNC_t rt_mutex_t /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||||
|
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
|
||||||
|
/
|
||||||
|
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||||
|
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||||
|
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||||
|
/ function must be added to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _FFCONFIG */
|
|
@ -6,7 +6,10 @@
|
||||||
|
|
||||||
#include "../ff.h"
|
#include "../ff.h"
|
||||||
|
|
||||||
#if _USE_LFN && _CODE_PAGE == 936
|
|
||||||
|
#if !_USE_LFN || _CODE_PAGE != 936
|
||||||
|
#error This file is not needed in current configuration.
|
||||||
|
#endif
|
||||||
|
|
||||||
static
|
static
|
||||||
const WCHAR uni2oem[] = {
|
const WCHAR uni2oem[] = {
|
||||||
|
@ -10968,5 +10971,3 @@ WCHAR ff_wtoupper ( /* Upper converted character */
|
||||||
|
|
||||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
/* Sample code of OS dependent synchronization object controls */
|
/* Sample code of OS dependent synchronization object controls */
|
||||||
/* for FatFs R0.07a (C)ChaN, 2009 */
|
/* for FatFs R0.07d (C)ChaN, 2009 */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include <windows.h> // Win32
|
#include <windows.h> // Win32
|
||||||
|
@ -78,11 +78,11 @@ BOOL ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not ge
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
ret = (WaitForSingleObject(sobj, _TIMEOUT) == WAIT_OBJECT_0) ? TRUE : FALSE; // Win32
|
ret = (WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0) ? TRUE : FALSE; // Win32
|
||||||
|
|
||||||
// ret = (wai_sem(sobj) == E_OK) ? TRUE : FALSE; // uITRON
|
// ret = (wai_sem(sobj) == E_OK) ? TRUE : FALSE; // uITRON
|
||||||
|
|
||||||
// OSMutexPend(sobj, _TIMEOUT, &err)); // uC/OS-II
|
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); // uC/OS-II
|
||||||
// ret = (err == OS_NO_ERR) ? TRUE : FALSE; //
|
// ret = (err == OS_NO_ERR) ? TRUE : FALSE; //
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue