[FatFS] Update to R0.13c (p3)

This commit is contained in:
Kostas Missos 2019-03-13 12:27:43 +02:00
parent ff9671c481
commit 491c4efe9c
7 changed files with 207 additions and 192 deletions

View file

@ -15,6 +15,9 @@
extern sdmmc_storage_t sd_storage; extern sdmmc_storage_t sd_storage;
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status ( DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */ BYTE pdrv /* Physical drive nmuber to identify the drive */
) )
@ -22,6 +25,9 @@ DSTATUS disk_status (
return 0; return 0;
} }
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize ( DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */ BYTE pdrv /* Physical drive nmuber to identify the drive */
) )
@ -29,6 +35,9 @@ DSTATUS disk_initialize (
return 0; return 0;
} }
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read ( DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */ BYTE *buff, /* Data buffer to store read data */
@ -38,7 +47,7 @@ DRESULT disk_read (
{ {
if ((u32)buff >= 0x90000000) if ((u32)buff >= 0x90000000)
return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR; return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR;
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
if (sdmmc_storage_read(&sd_storage, sector, count, buf)) if (sdmmc_storage_read(&sd_storage, sector, count, buf))
{ {
memcpy(buff, buf, 512 * count); memcpy(buff, buf, 512 * count);
@ -47,6 +56,9 @@ DRESULT disk_read (
return RES_ERROR; return RES_ERROR;
} }
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_write ( DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */ const BYTE *buff, /* Data to be written */
@ -63,6 +75,9 @@ DRESULT disk_write (
return RES_ERROR; return RES_ERROR;
} }
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl ( DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */ BYTE cmd, /* Control code */

View file

@ -11,7 +11,6 @@ extern "C" {
#include "../../utils/types.h" #include "../../utils/types.h"
/* Status of Disk Functions */ /* Status of Disk Functions */
typedef BYTE DSTATUS; typedef BYTE DSTATUS;
@ -46,11 +45,11 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Command code for disk_ioctrl fucntion */ /* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */ /* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */ /* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */ #define CTRL_POWER 5 /* Get/Set power status */

View file

@ -1,10 +1,10 @@
/*----------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem Module R0.13b / / FatFs - Generic FAT Filesystem Module R0.13c (p3) /
/-----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ /
/ Copyright (C) 2018, ChaN, all right reserved. / Copyright (C) 2018, ChaN, all right reserved.
/ Copyright (c) 2018 naehrwert / Copyright (c) 2018 naehrwert
/ Copyright (C) 2018 CTCaer / Copyright (C) 2018-2019 CTCaer
/ /
/ FatFs module is an open source software. Redistribution and use of FatFs in / FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided / source and binary forms, with or without modification, are permitted provided
@ -34,11 +34,20 @@
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#if FF_DEFINED != 63463 /* Revision ID */ #if FF_DEFINED != 86604 /* Revision ID */
#error Wrong include file (ff.h). #error Wrong include file (ff.h).
#endif #endif
/* Limits and boundaries */
#define MAX_DIR 0x200000 /* Max size of FAT directory */
#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */
#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */
#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */
#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */
#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */
/* Character code support macros */ /* Character code support macros */
#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')
@ -48,18 +57,18 @@
#define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) #define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF)
/* Additional file attribute bits for internal use */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Additional file access control and file status flags for internal use */ /* Additional file access control and file status flags for internal use */
#define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ #define FA_SEEKEND 0x20 /* Seek to end of the file on file open */
#define FA_MODIFIED 0x40 /* File has been modified */ #define FA_MODIFIED 0x40 /* File has been modified */
#define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ #define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */
/* Additional file attribute bits for internal use */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Name status flags in fn[11] */ /* Name status flags in fn[11] */
#define NSFLAG 11 /* Index of the name status byte */ #define NSFLAG 11 /* Index of the name status byte */
#define NS_LOSS 0x01 /* Out of 8.3 format */ #define NS_LOSS 0x01 /* Out of 8.3 format */
@ -72,13 +81,13 @@
#define NS_NONAME 0x80 /* Not followed */ #define NS_NONAME 0x80 /* Not followed */
/* Limits and boundaries */ /* exFAT directory entry types */
#define MAX_DIR 0x200000 /* Max size of FAT directory */ #define ET_BITMAP 0x81 /* Allocation bitmap */
#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ #define ET_UPCASE 0x82 /* Up-case table */
#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ #define ET_VLABEL 0x83 /* Volume label */
#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ #define ET_FILEDIR 0x85 /* File and directory */
#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ #define ET_STREAM 0xC0 /* Stream extension */
#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ #define ET_FILENAME 0xC1 /* Name extension */
/* FatFs refers the FAT structure as simple byte array instead of structure member /* FatFs refers the FAT structure as simple byte array instead of structure member
@ -526,6 +535,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */
#define CODEPAGE CodePage #define CODEPAGE CodePage
static WORD CodePage; /* Current code page */ static WORD CodePage; /* Current code page */
static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */
static const BYTE Ct437[] = TBL_CT437; static const BYTE Ct437[] = TBL_CT437;
static const BYTE Ct720[] = TBL_CT720; static const BYTE Ct720[] = TBL_CT720;
static const BYTE Ct737[] = TBL_CT737; static const BYTE Ct737[] = TBL_CT737;
@ -1107,7 +1117,7 @@ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */
if (res == FR_OK) { if (res == FR_OK) {
if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */
/* Create FSInfo structure */ /* Create FSInfo structure */
mem_set(fs->win, 0, SS(fs)); mem_set(fs->win, 0, sizeof fs->win);
st_word(fs->win + BS_55AA, 0xAA55); st_word(fs->win + BS_55AA, 0xAA55);
st_dword(fs->win + FSI_LeadSig, 0x41615252); st_dword(fs->win + FSI_LeadSig, 0x41615252);
st_dword(fs->win + FSI_StrucSig, 0x61417272); st_dword(fs->win + FSI_StrucSig, 0x61417272);
@ -1307,7 +1317,7 @@ static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:D
if (clst >= fs->n_fatent - 2) clst = 0; if (clst >= fs->n_fatent - 2) clst = 0;
scl = val = clst; ctr = 0; scl = val = clst; ctr = 0;
for (;;) { for (;;) {
if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF;
i = val / 8 % SS(fs); bm = 1 << (val % 8); i = val / 8 % SS(fs); bm = 1 << (val % 8);
do { do {
do { do {
@ -1345,9 +1355,9 @@ static FRESULT change_bitmap (
clst -= 2; /* The first bit corresponds to cluster #2 */ clst -= 2; /* The first bit corresponds to cluster #2 */
sect = fs->database + clst / 8 / SS(fs); /* Sector address (assuming bitmap is located top of the cluster heap) */ sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */
i = clst / 8 % SS(fs); /* Byte offset in the sector */ i = clst / 8 % SS(fs); /* Byte offset in the sector */
bm = 1 << (clst % 8); /* Bit mask in the byte */ bm = 1 << (clst % 8); /* Bit mask in the byte */
for (;;) { for (;;) {
if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR;
do { do {
@ -1420,7 +1430,7 @@ static FRESULT fill_last_frag (
static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */
FFOBJID* obj, /* Corresponding object */ FFOBJID* obj, /* Corresponding object */
DWORD clst, /* Cluster to remove a chain from */ DWORD clst, /* Cluster to remove a chain from */
DWORD pclst /* Previous cluster of clst (0:entire chain) */ DWORD pclst /* Previous cluster of clst (0 if entire chain) */
) )
{ {
FRESULT res = FR_OK; FRESULT res = FR_OK;
@ -1658,7 +1668,7 @@ static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */
if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */
sect = clst2sect(fs, clst); /* Top of the cluster */ sect = clst2sect(fs, clst); /* Top of the cluster */
fs->winsect = sect; /* Set window to top of the cluster */ fs->winsect = sect; /* Set window to top of the cluster */
mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */ mem_set(fs->win, 0, sizeof fs->win); /* Clear window buffer */
#if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ #if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */
/* Allocate a temporary buffer */ /* Allocate a temporary buffer */
for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ;
@ -1888,7 +1898,7 @@ static int cmp_lfn ( /* 1:matched, 0:not matched */
for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */
uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */
if (wc != 0) { if (wc != 0) {
if (i >= FF_MAX_LFN || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */ if (i >= FF_MAX_LFN + 1 || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++])) { /* Compare it */
return 0; /* Not matched */ return 0; /* Not matched */
} }
wc = uc; wc = uc;
@ -1924,15 +1934,15 @@ static int pick_lfn ( /* 1:succeeded, 0:buffer overflow or invalid LFN entry */
for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */ for (wc = 1, s = 0; s < 13; s++) { /* Process all characters in the entry */
uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */ uc = ld_word(dir + LfnOfs[s]); /* Pick an LFN character */
if (wc != 0) { if (wc != 0) {
if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */
lfnbuf[i++] = wc = uc; /* Store it */ lfnbuf[i++] = wc = uc; /* Store it */
} else { } else {
if (uc != 0xFFFF) return 0; /* Check filler */ if (uc != 0xFFFF) return 0; /* Check filler */
} }
} }
if (dir[LDIR_Ord] & LLEF) { /* Put terminator if it is the last LFN part */ if (dir[LDIR_Ord] & LLEF && wc != 0) { /* Put terminator if it is the last LFN part and not terminated */
if (i >= FF_MAX_LFN) return 0; /* Buffer overflow? */ if (i >= FF_MAX_LFN + 1) return 0; /* Buffer overflow? */
lfnbuf[i] = 0; lfnbuf[i] = 0;
} }
@ -2168,33 +2178,33 @@ static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */
BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */
/* Load 85 entry */ /* Load file-directory entry */
res = move_window(dp->obj.fs, dp->sect); res = move_window(dp->obj.fs, dp->sect);
if (res != FR_OK) return res; if (res != FR_OK) return res;
if (dp->dir[XDIR_Type] != 0x85) return FR_INT_ERR; /* Invalid order */ if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */
mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE);
sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE;
if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR;
/* Load C0 entry */ /* Load stream-extension entry */
res = dir_next(dp, 0); res = dir_next(dp, 0);
if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */
if (res != FR_OK) return res; if (res != FR_OK) return res;
res = move_window(dp->obj.fs, dp->sect); res = move_window(dp->obj.fs, dp->sect);
if (res != FR_OK) return res; if (res != FR_OK) return res;
if (dp->dir[XDIR_Type] != 0xC0) return FR_INT_ERR; /* Invalid order */ if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */
mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE);
if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR;
/* Load C1 entries */ /* Load file-name entries */
i = 2 * SZDIRE; /* C1 offset to load */ i = 2 * SZDIRE; /* Name offset to load */
do { do {
res = dir_next(dp, 0); res = dir_next(dp, 0);
if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */
if (res != FR_OK) return res; if (res != FR_OK) return res;
res = move_window(dp->obj.fs, dp->sect); res = move_window(dp->obj.fs, dp->sect);
if (res != FR_OK) return res; if (res != FR_OK) return res;
if (dp->dir[XDIR_Type] != 0xC1) return FR_INT_ERR; /* Invalid order */ if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */
if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE); if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE);
} while ((i += SZDIRE) < sz_ent); } while ((i += SZDIRE) < sz_ent);
@ -2299,16 +2309,16 @@ static void create_xdir (
WCHAR wc; WCHAR wc;
/* Create 85,C0 entry */ /* Create file-directory and stream-extension entry */
mem_set(dirb, 0, 2 * SZDIRE); mem_set(dirb, 0, 2 * SZDIRE);
dirb[0 * SZDIRE + XDIR_Type] = 0x85; /* 85 entry */ dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR;
dirb[1 * SZDIRE + XDIR_Type] = 0xC0; /* C0 entry */ dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM;
/* Create C1 entries */ /* Create file-name entries */
i = SZDIRE * 2; /* Top of C1 entries */ i = SZDIRE * 2; /* Top of file_name entries */
nlen = nc1 = 0; wc = 1; nlen = nc1 = 0; wc = 1;
do { do {
dirb[i++] = 0xC1; dirb[i++] = 0; /* Entry type C1 */ dirb[i++] = ET_FILENAME; dirb[i++] = 0;
do { /* Fill name field */ do { /* Fill name field */
if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */
st_word(dirb + i, wc); /* Store it */ st_word(dirb + i, wc); /* Store it */
@ -2332,8 +2342,8 @@ static void create_xdir (
/* Read an object from the directory */ /* Read an object from the directory */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
#define dir_read_file(dp) dir_read(dp, 0) #define DIR_READ_FILE(dp) dir_read(dp, 0)
#define dir_read_label(dp) dir_read(dp, 1) #define DIR_READ_LABEL(dp) dir_read(dp, 1)
static FRESULT dir_read ( static FRESULT dir_read (
DIR* dp, /* Pointer to the directory object */ DIR* dp, /* Pointer to the directory object */
@ -2342,7 +2352,7 @@ static FRESULT dir_read (
{ {
FRESULT res = FR_NO_FILE; FRESULT res = FR_NO_FILE;
FATFS *fs = dp->obj.fs; FATFS *fs = dp->obj.fs;
BYTE a, c; BYTE attr, b;
#if FF_USE_LFN #if FF_USE_LFN
BYTE ord = 0xFF, sum = 0xFF; BYTE ord = 0xFF, sum = 0xFF;
#endif #endif
@ -2350,16 +2360,16 @@ static FRESULT dir_read (
while (dp->sect) { while (dp->sect) {
res = move_window(fs, dp->sect); res = move_window(fs, dp->sect);
if (res != FR_OK) break; if (res != FR_OK) break;
c = dp->dir[DIR_Name]; /* Test for the entry type */ b = dp->dir[DIR_Name]; /* Test for the entry type */
if (c == 0) { if (b == 0) {
res = FR_NO_FILE; break; /* Reached to end of the directory */ res = FR_NO_FILE; break; /* Reached to end of the directory */
} }
#if FF_FS_EXFAT #if FF_FS_EXFAT
if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
if (FF_USE_LABEL && vol) { if (FF_USE_LABEL && vol) {
if (c == 0x83) break; /* Volume label entry? */ if (b == ET_VLABEL) break; /* Volume label entry? */
} else { } else {
if (c == 0x85) { /* Start of the file entry block? */ if (b == ET_FILEDIR) { /* Start of the file entry block? */
dp->blk_ofs = dp->dptr; /* Get location of the block */ dp->blk_ofs = dp->dptr; /* Get location of the block */
res = load_xdir(dp); /* Load the entry block */ res = load_xdir(dp); /* Load the entry block */
if (res == FR_OK) { if (res == FR_OK) {
@ -2371,19 +2381,19 @@ static FRESULT dir_read (
} else } else
#endif #endif
{ /* On the FAT/FAT32 volume */ { /* On the FAT/FAT32 volume */
dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */
#if FF_USE_LFN /* LFN configuration */ #if FF_USE_LFN /* LFN configuration */
if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */
ord = 0xFF; ord = 0xFF;
} else { } else {
if (a == AM_LFN) { /* An LFN entry is found */ if (attr == AM_LFN) { /* An LFN entry is found */
if (c & LLEF) { /* Is it start of an LFN sequence? */ if (b & LLEF) { /* Is it start of an LFN sequence? */
sum = dp->dir[LDIR_Chksum]; sum = dp->dir[LDIR_Chksum];
c &= (BYTE)~LLEF; ord = c; b &= (BYTE)~LLEF; ord = b;
dp->blk_ofs = dp->dptr; dp->blk_ofs = dp->dptr;
} }
/* Check LFN validity and capture it */ /* Check LFN validity and capture it */
ord = (c == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF;
} else { /* An SFN entry is found */ } else { /* An SFN entry is found */
if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */
dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */
@ -2392,7 +2402,7 @@ static FRESULT dir_read (
} }
} }
#else /* Non LFN configuration */ #else /* Non LFN configuration */
if (c != DDEM && c != '.' && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */
break; break;
} }
#endif #endif
@ -2432,7 +2442,7 @@ static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */
UINT di, ni; UINT di, ni;
WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */
while ((res = dir_read_file(dp)) == FR_OK) { /* Read an item */ while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */
#if FF_MAX_LFN < 255 #if FF_MAX_LFN < 255
if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */
#endif #endif
@ -2511,17 +2521,17 @@ static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too
#if FF_FS_EXFAT #if FF_FS_EXFAT
if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */
nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */
res = dir_alloc(dp, nent); /* Allocate entries */ res = dir_alloc(dp, nent); /* Allocate directory entries */
if (res != FR_OK) return res; if (res != FR_OK) return res;
dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */ dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */
if (dp->obj.stat & 4) { /* Has the directory been stretched? */ if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */
dp->obj.stat &= ~4; dp->obj.stat &= ~4;
res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */
if (res != FR_OK) return res; if (res != FR_OK) return res;
res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */
if (res != FR_OK) return res; if (res != FR_OK) return res;
if (dp->obj.sclust != 0) { /* Is it a sub directory? */ if (dp->obj.sclust != 0) { /* Is it a sub-directory? */
DIR dj; DIR dj;
res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */
@ -2653,6 +2663,7 @@ static void get_fileinfo (
{ {
UINT si, di; UINT si, di;
#if FF_USE_LFN #if FF_USE_LFN
BYTE lcf;
WCHAR wc, hs; WCHAR wc, hs;
FATFS *fs = dp->obj.fs; FATFS *fs = dp->obj.fs;
#else #else
@ -2713,9 +2724,10 @@ static void get_fileinfo (
if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */ if (di == 0) { /* If LFN and SFN both are invalid, this object is inaccesible */
fno->fname[di++] = '?'; fno->fname[di++] = '?';
} else { } else {
for (si = di = 0; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */ for (si = di = 0, lcf = NS_BODY; fno->altname[si]; si++, di++) { /* Copy altname[] to fname[] with case information */
wc = (WCHAR)fno->altname[si]; wc = (WCHAR)fno->altname[si];
if (IsUpper(wc) && (dp->dir[DIR_NTres] & ((si >= 9) ? NS_EXT : NS_BODY))) wc += 0x20; if (wc == '.') lcf = NS_EXT;
if (IsUpper(wc) && (dp->dir[DIR_NTres] & lcf)) wc += 0x20;
fno->fname[di] = (TCHAR)wc; fno->fname[di] = (TCHAR)wc;
} }
} }
@ -3272,7 +3284,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
#endif #endif
/* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK and SFD. */ /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */
bsect = 0; bsect = 0;
fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */
if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */ if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */
@ -3301,13 +3313,12 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
#if FF_FS_EXFAT #if FF_FS_EXFAT
if (fmt == 1) { if (fmt == 1) {
QWORD maxlba; QWORD maxlba;
DWORD so, cv, bcl;
for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */
if (i < BPB_ZeroedEx + 53) if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM;
return FR_NO_FILESYSTEM;
if (ld_word(fs->win + BPB_FSVerEx) != 0x100) if (ld_word(fs->win + BPB_FSVerEx) != 0x100) return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */
return FR_NO_FILESYSTEM; /* Check exFAT version (must be version 1.0) */
if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */ if (1 << fs->win[BPB_BytsPerSecEx] != SS(fs)) { /* (BPB_BytsPerSecEx must be equal to the physical sector size) */
EFSPRINTF("EXSPS"); EFSPRINTF("EXSPS");
@ -3315,8 +3326,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
} }
maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */ maxlba = ld_qword(fs->win + BPB_TotSecEx) + bsect; /* Last LBA + 1 of the volume */
if (maxlba >= 0x100000000) if (maxlba >= 0x100000000) return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */
return FR_NO_FILESYSTEM; /* (It cannot be handled in 32-bit LBA) */
fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */ fs->fsize = ld_dword(fs->win + BPB_FatSzEx); /* Number of sectors per FAT */
@ -3327,35 +3337,49 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
} }
fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */ fs->csize = 1 << fs->win[BPB_SecPerClusEx]; /* Cluster size */
if (fs->csize == 0) { if (fs->csize == 0) return FR_NO_FILESYSTEM; /* (Must be 1..32768) */
return FR_NO_FILESYSTEM; /* (Must be 1..32768) */
}
nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */ nclst = ld_dword(fs->win + BPB_NumClusEx); /* Number of clusters */
if (nclst > MAX_EXFAT) if (nclst > MAX_EXFAT) return FR_NO_FILESYSTEM; /* (Too many clusters) */
return FR_NO_FILESYSTEM; /* (Too many clusters) */
fs->n_fatent = nclst + 2; fs->n_fatent = nclst + 2;
/* Boundaries and Limits */ /* Boundaries and Limits */
fs->volbase = bsect; fs->volbase = bsect;
fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx);
fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx);
if (maxlba < (QWORD)fs->database + nclst * fs->csize) if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */
return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size required) */
fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); fs->dirbase = ld_dword(fs->win + BPB_RootClusEx);
/* Check if bitmap location is in assumption (at the first cluster) */ /* Get bitmap location and check if it is contiguous (implementation assumption) */
if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) { so = i = 0;
EFSPRINTF("EXBM1C"); for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */
return FR_DISK_ERR; if (i == 0) {
if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */
if (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) {
EFSPRINTF("EXBM1C");
return FR_DISK_ERR;
}
so++;
}
if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */
i = (i + SZDIRE) % SS(fs); /* Next entry */
} }
for (i = 0; i < SS(fs); i += SZDIRE) { bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */
if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */ if (bcl < 2 || bcl >= fs->n_fatent) {
}
if (i == SS(fs)) {
EFSPRINTF("EXBMM"); EFSPRINTF("EXBMM");
return FR_NO_FILESYSTEM; return FR_NO_FILESYSTEM;
} }
fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */
for (;;) { /* Check if bitmap is contiguous */
if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR;
cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4);
if (cv == 0xFFFFFFFF) break; /* Last link? */
if (cv != ++bcl) {
EFSPRINTF("EXBMM");
return FR_NO_FILESYSTEM; /* Fragmented? */
}
}
#if !FF_FS_READONLY #if !FF_FS_READONLY
fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */
#endif #endif
@ -3373,38 +3397,31 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->fsize = fasize; fs->fsize = fasize;
fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */
if (fs->n_fats != 1 && fs->n_fats != 2) if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */
fasize *= fs->n_fats; /* Number of sectors for FAT area */ fasize *= fs->n_fats; /* Number of sectors for FAT area */
fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */
if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) if (fs->csize == 0 || (fs->csize & (fs->csize - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
return FR_NO_FILESYSTEM; /* (Must be power of 2) */
fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */ fs->n_rootdir = ld_word(fs->win + BPB_RootEntCnt); /* Number of root directory entries */
if (fs->n_rootdir % (SS(fs) / SZDIRE)) if (fs->n_rootdir % (SS(fs) / SZDIRE)) return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
return FR_NO_FILESYSTEM; /* (Must be sector aligned) */
tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */ tsect = ld_word(fs->win + BPB_TotSec16); /* Number of sectors on the volume */
if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32); if (tsect == 0) tsect = ld_dword(fs->win + BPB_TotSec32);
nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */ nrsv = ld_word(fs->win + BPB_RsvdSecCnt); /* Number of reserved sectors */
if (nrsv == 0) if (nrsv == 0) return FR_NO_FILESYSTEM; /* (Must not be 0) */
return FR_NO_FILESYSTEM; /* (Must not be 0) */
/* Determine the FAT sub type */ /* Determine the FAT sub type */
sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + DIR */
if (tsect < sysect) if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */
if (nclst == 0) if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */
return FR_NO_FILESYSTEM; /* (Invalid volume size) */
fmt = 0; fmt = 0;
if (nclst <= MAX_FAT32) fmt = FS_FAT32; if (nclst <= MAX_FAT32) fmt = FS_FAT32;
if (nclst <= MAX_FAT16) fmt = FS_FAT16; if (nclst <= MAX_FAT16) fmt = FS_FAT16;
if (nclst <= MAX_FAT12) fmt = FS_FAT12; if (nclst <= MAX_FAT12) fmt = FS_FAT12;
if (fmt == 0) if (fmt == 0) return FR_NO_FILESYSTEM;
return FR_NO_FILESYSTEM;
/* Boundaries and Limits */ /* Boundaries and Limits */
fs->n_fatent = nclst + 2; /* Number of FAT entries */ fs->n_fatent = nclst + 2; /* Number of FAT entries */
@ -3412,21 +3429,17 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->fatbase = bsect + nrsv; /* FAT start sector */ fs->fatbase = bsect + nrsv; /* FAT start sector */
fs->database = bsect + sysect; /* Data start sector */ fs->database = bsect + sysect; /* Data start sector */
if (fmt == FS_FAT32) { if (fmt == FS_FAT32) {
if (ld_word(fs->win + BPB_FSVer32) != 0) if (ld_word(fs->win + BPB_FSVer32) != 0) return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */
return FR_NO_FILESYSTEM; /* (Must be FAT32 revision 0.0) */ if (fs->n_rootdir != 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
if (fs->n_rootdir != 0)
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */
fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */ fs->dirbase = ld_dword(fs->win + BPB_RootClus32); /* Root directory start cluster */
szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ szbfat = fs->n_fatent * 4; /* (Needed FAT size) */
} else { } else {
if (fs->n_rootdir == 0) if (fs->n_rootdir == 0) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */
fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */
szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */
fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
} }
if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
return FR_NO_FILESYSTEM; /* (BPB_FATSz must not be less than the size needed) */
#if !FF_FS_READONLY #if !FF_FS_READONLY
/* Get FSInfo if available */ /* Get FSInfo if available */
@ -3459,7 +3472,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
#if FF_USE_LFN == 1 #if FF_USE_LFN == 1
fs->lfnbuf = LfnBuf; /* Static LFN working buffer */ fs->lfnbuf = LfnBuf; /* Static LFN working buffer */
#if FF_FS_EXFAT #if FF_FS_EXFAT
fs->dirbuf = DirBuf; /* Static directory block scratchpad buffer */ fs->dirbuf = DirBuf; /* Static directory block scratchpad buuffer */
#endif #endif
#endif #endif
#if FF_FS_RPATH != 0 #if FF_FS_RPATH != 0
@ -3722,7 +3735,7 @@ FRESULT f_open (
fp->fptr = 0; /* Set file pointer top of the file */ fp->fptr = 0; /* Set file pointer top of the file */
#if !FF_FS_READONLY #if !FF_FS_READONLY
#if !FF_FS_TINY #if !FF_FS_TINY
mem_set(fp->buf, 0, FF_MAX_SS); /* Clear sector buffer */ mem_set(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */
#endif #endif
if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */
fp->fptr = fp->obj.objsize; /* Offset to seek */ fp->fptr = fp->obj.objsize; /* Offset to seek */
@ -3819,9 +3832,7 @@ FRESULT f_read (
fp->clust = clst; /* Update current cluster */ fp->clust = clst; /* Update current cluster */
} }
sect = clst2sect(fs, fp->clust); /* Get current sector */ sect = clst2sect(fs, fp->clust); /* Get current sector */
if (sect == 0) { if (sect == 0) ABORT(fs, FR_INT_ERR);
ABORT(fs, FR_INT_ERR);
}
sect += csect; sect += csect;
cc = btr / SS(fs); /* When remaining bytes >= sector size, */ cc = btr / SS(fs); /* When remaining bytes >= sector size, */
if (cc > 0) { /* Read maximum contiguous sectors directly */ if (cc > 0) { /* Read maximum contiguous sectors directly */
@ -3906,10 +3917,7 @@ FRESULT f_write (
EFSPRINTF("FOV"); EFSPRINTF("FOV");
LEAVE_FF(fs, res); /* Check validity */ LEAVE_FF(fs, res); /* Check validity */
} }
if (!(fp->flag & FA_WRITE)) { if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
EFSPRINTF("NOACCESS");
LEAVE_FF(fs, FR_DENIED); /* Check access mode */
}
/* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */ /* Check fptr wrap-around (file size cannot reach 4 GiB at FAT volume) */
if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) { if ((!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
@ -3955,15 +3963,12 @@ FRESULT f_write (
if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */ if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
#else #else
if (fp->flag & FA_DIRTY) { /* Write-back sector cache */ if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY; fp->flag &= (BYTE)~FA_DIRTY;
} }
#endif #endif
sect = clst2sect(fs, fp->clust); /* Get current sector */ sect = clst2sect(fs, fp->clust); /* Get current sector */
if (sect == 0) { if (sect == 0) ABORT(fs, FR_INT_ERR);
ABORT(fs, FR_INT_ERR);
}
sect += csect; sect += csect;
cc = btw / SS(fs); /* When remaining bytes >= sector size, */ cc = btw / SS(fs); /* When remaining bytes >= sector size, */
if (cc > 0) { /* Write maximum contiguous sectors directly */ if (cc > 0) { /* Write maximum contiguous sectors directly */
@ -3998,8 +4003,9 @@ FRESULT f_write (
#else #else
if (fp->sect != sect && /* Fill sector cache with file data */ if (fp->sect != sect && /* Fill sector cache with file data */
fp->fptr < fp->obj.objsize && fp->fptr < fp->obj.objsize &&
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
ABORT(fs, FR_DISK_ERR); ABORT(fs, FR_DISK_ERR);
}
#endif #endif
fp->sect = sect; fp->sect = sect;
} }
@ -4245,6 +4251,7 @@ FRESULT f_getcwd (
/* Get logical drive */ /* Get logical drive */
buff[0] = 0; /* Set null string to get current volume */
res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */
if (res == FR_OK) { if (res == FR_OK) {
dj.obj.fs = fs; dj.obj.fs = fs;
@ -4263,7 +4270,7 @@ FRESULT f_getcwd (
res = dir_sdi(&dj, 0); res = dir_sdi(&dj, 0);
if (res != FR_OK) break; if (res != FR_OK) break;
do { /* Find the entry links to the child directory */ do { /* Find the entry links to the child directory */
res = dir_read_file(&dj); res = DIR_READ_FILE(&dj);
if (res != FR_OK) break; if (res != FR_OK) break;
if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */
res = dir_next(&dj, 0); res = dir_next(&dj, 0);
@ -4595,7 +4602,7 @@ FRESULT f_readdir (
res = dir_sdi(dp, 0); /* Rewind the directory object */ res = dir_sdi(dp, 0); /* Rewind the directory object */
} else { } else {
INIT_NAMBUF(fs); INIT_NAMBUF(fs);
res = dir_read_file(dp); /* Read an item */ res = DIR_READ_FILE(dp); /* Read an item */
if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */
if (res == FR_OK) { /* A valid entry is found */ if (res == FR_OK) { /* A valid entry is found */
get_fileinfo(dp, fno); /* Get the object information */ get_fileinfo(dp, fno); /* Get the object information */
@ -4740,7 +4747,7 @@ FRESULT f_getfree (
UINT b; UINT b;
clst = fs->n_fatent - 2; /* Number of clusters */ clst = fs->n_fatent - 2; /* Number of clusters */
sect = fs->database; /* Assuming bitmap starts at cluster 2 */ sect = fs->bitbase; /* Bitmap sector */
i = 0; /* Offset in the sector */ i = 0; /* Offset in the sector */
do { /* Counts numbuer of bits with zero in the bitmap */ do { /* Counts numbuer of bits with zero in the bitmap */
if (i == 0) { if (i == 0) {
@ -4903,7 +4910,7 @@ FRESULT f_unlink (
#endif #endif
res = dir_sdi(&sdj, 0); res = dir_sdi(&sdj, 0);
if (res == FR_OK) { if (res == FR_OK) {
res = dir_read_file(&sdj); /* Test if the directory is empty */ res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */
if (res == FR_OK) res = FR_DENIED; /* Not empty? */ if (res == FR_OK) res = FR_DENIED; /* Not empty? */
if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ if (res == FR_NO_FILE) res = FR_OK; /* Empty? */
} }
@ -4943,47 +4950,43 @@ FRESULT f_mkdir (
DIR dj; DIR dj;
FFOBJID sobj; FFOBJID sobj;
FATFS *fs; FATFS *fs;
BYTE *dir;
DWORD dcl, pcl, tm; DWORD dcl, pcl, tm;
DEF_NAMBUF DEF_NAMBUF
/* Get logical drive */ res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */
res = find_volume(&path, &fs, FA_WRITE);
if (res == FR_OK) { if (res == FR_OK) {
dj.obj.fs = fs; dj.obj.fs = fs;
INIT_NAMBUF(fs); INIT_NAMBUF(fs);
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 object with same name is already existing */ if (res == FR_OK) res = FR_EXIST; /* Name collision? */
if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */
res = FR_INVALID_NAME; res = FR_INVALID_NAME;
} }
if (res == FR_NO_FILE) { /* Can create a new directory */ if (res == FR_NO_FILE) { /* It is clear to create a new directory */
sobj.fs = fs; /* New object id to create a new chain */ sobj.fs = fs; /* New object id to create a new chain */
dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */
res = FR_OK; res = FR_OK;
if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */
if (dcl == 1) res = FR_INT_ERR; if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */
if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */
if (res == FR_OK) res = sync_window(fs); /* Flush FAT */
tm = GET_FATTIME(); tm = GET_FATTIME();
if (res == FR_OK) { /* Initialize the new directory table */
res = dir_clear(fs, dcl); /* Clean up the new table */
if (res == FR_OK && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT)) { /* Create dot entries (FAT only) */
dir = fs->win;
mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */
dir[DIR_Name] = '.';
dir[DIR_Attr] = AM_DIR;
st_dword(dir + DIR_ModTime, tm);
st_clust(fs, dir, dcl);
mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */
dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;
st_clust(fs, dir + SZDIRE, pcl);
fs->wflag = 1;
}
}
if (res == FR_OK) { if (res == FR_OK) {
res = dir_register(&dj); /* Register the object to the directoy */ res = dir_clear(fs, dcl); /* Clean up the new table */
if (res == FR_OK) {
if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */
mem_set(fs->win + DIR_Name, ' ', 11); /* Create "." entry */
fs->win[DIR_Name] = '.';
fs->win[DIR_Attr] = AM_DIR;
st_dword(fs->win + DIR_ModTime, tm);
st_clust(fs, fs->win, dcl);
mem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */
fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;
st_clust(fs, fs->win + SZDIRE, pcl);
fs->wflag = 1;
}
res = dir_register(&dj); /* Register the object to the parent directoy */
}
} }
if (res == FR_OK) { if (res == FR_OK) {
#if FF_FS_EXFAT #if FF_FS_EXFAT
@ -4998,17 +5001,16 @@ FRESULT f_mkdir (
} else } else
#endif #endif
{ {
dir = dj.dir; st_dword(dj.dir + DIR_ModTime, tm); /* Created time */
st_dword(dir + DIR_ModTime, tm); /* Created time */ st_clust(fs, dj.dir, dcl); /* Table start cluster */
st_clust(fs, dir, dcl); /* Table start cluster */ dj.dir[DIR_Attr] = AM_DIR; /* Attribute */
dir[DIR_Attr] = AM_DIR; /* Attribute */
fs->wflag = 1; fs->wflag = 1;
} }
if (res == FR_OK) { if (res == FR_OK) {
res = sync_fs(fs); res = sync_fs(fs);
} }
} else { } else {
remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */ remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */
} }
} }
FREE_NAMBUF(); FREE_NAMBUF();
@ -5248,7 +5250,7 @@ FRESULT f_getlabel (
dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
res = dir_sdi(&dj, 0); res = dir_sdi(&dj, 0);
if (res == FR_OK) { if (res == FR_OK) {
res = dir_read_label(&dj); /* Find a volume label entry */ res = DIR_READ_LABEL(&dj); /* Find a volume label entry */
if (res == FR_OK) { if (res == FR_OK) {
#if FF_FS_EXFAT #if FF_FS_EXFAT
if (fs->fs_type == FS_EXFAT) { if (fs->fs_type == FS_EXFAT) {
@ -5393,7 +5395,7 @@ FRESULT f_setlabel (
dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */
res = dir_sdi(&dj, 0); res = dir_sdi(&dj, 0);
if (res == FR_OK) { if (res == FR_OK) {
res = dir_read_label(&dj); /* Get volume label entry */ res = DIR_READ_LABEL(&dj); /* Get volume label entry */
if (res == FR_OK) { if (res == FR_OK) {
if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */
@ -5415,7 +5417,7 @@ FRESULT f_setlabel (
if (res == FR_OK) { if (res == FR_OK) {
mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */ mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */
if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) {
dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */
dj.dir[XDIR_NumLabel] = (BYTE)di; dj.dir[XDIR_NumLabel] = (BYTE)di;
mem_cpy(dj.dir + XDIR_Label, dirvn, 22); mem_cpy(dj.dir + XDIR_Label, dirvn, 22);
} else { } else {
@ -5720,7 +5722,7 @@ FRESULT f_mkfs (
b_fat = b_vol + 32; /* FAT start at offset 32 */ b_fat = b_vol + 32; /* FAT start at offset 32 */
sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */ sz_fat = ((sz_vol / au + 2) * 4 + ss - 1) / ss; /* Number of FAT sectors */
b_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1); /* Align data area to the erase block boundary */ b_data = (b_fat + sz_fat + sz_blk - 1) & ~(sz_blk - 1); /* Align data area to the erase block boundary */
if (b_data >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */ if (b_data - b_vol >= sz_vol / 2) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume? */
n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */ n_clst = (sz_vol - (b_data - b_vol)) / au; /* Number of clusters */
if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */ if (n_clst <16) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too few clusters? */
if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */ if (n_clst > MAX_EXFAT) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too many clusters? */
@ -5801,11 +5803,11 @@ FRESULT f_mkfs (
/* Initialize the root directory */ /* Initialize the root directory */
mem_set(buf, 0, szb_buf); mem_set(buf, 0, szb_buf);
buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry */
buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */
st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */
st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */
buf[SZDIRE * 2 + 0] = 0x82; /* 82 entry (up-case table) */ buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */
st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */
st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */ st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */
st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */
@ -6293,8 +6295,7 @@ typedef struct { /* Putchar output buffer and work area */
} putbuff; } putbuff;
static static void putc_bfd ( /* Buffered write with code conversion */
void putc_bfd ( /* Buffered write with code conversion */
putbuff* pb, putbuff* pb,
TCHAR c TCHAR c
) )
@ -6405,7 +6406,7 @@ void putc_bfd ( /* Buffered write with code conversion */
#else /* Write it in ANSI/OEM */ #else /* Write it in ANSI/OEM */
if (hs != 0) return; if (hs != 0) return;
wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */
if (wc == 0) return;; if (wc == 0) return;
if (wc >= 0x100) { if (wc >= 0x100) {
pb->buf[i++] = (BYTE)(wc >> 8); nc++; pb->buf[i++] = (BYTE)(wc >> 8); nc++;
} }
@ -6425,8 +6426,7 @@ void putc_bfd ( /* Buffered write with code conversion */
} }
static static int putc_flush ( /* Flush left characters in the buffer */
int putc_flush ( /* Flush left characters in the buffer */
putbuff* pb putbuff* pb
) )
{ {
@ -6439,8 +6439,7 @@ int putc_flush ( /* Flush left characters in the buffer */
} }
static static void putc_init ( /* Initialize write buffer */
void putc_init ( /* Initialize write buffer */
putbuff* pb, putbuff* pb,
FIL* fp FIL* fp
) )

View file

@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------/ /*----------------------------------------------------------------------------/
/ FatFs - Generic FAT Filesystem module R0.13b / / FatFs - Generic FAT Filesystem module R0.13c /
/-----------------------------------------------------------------------------/ /-----------------------------------------------------------------------------/
/ /
/ Copyright (C) 2018, ChaN, all right reserved. / Copyright (C) 2018, ChaN, all right reserved.
@ -20,7 +20,7 @@
#ifndef FF_DEFINED #ifndef FF_DEFINED
#define FF_DEFINED 63463 /* Revision ID */ #define FF_DEFINED 86604 /* Revision ID */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -95,8 +95,8 @@ typedef DWORD FSIZE_t;
/* Filesystem object structure (FATFS) */ /* Filesystem object structure (FATFS) */
typedef struct { typedef struct {
BYTE fs_type; /* Filesystem type (0:N/A) */ BYTE fs_type; /* Filesystem type (0:not mounted) */
BYTE pdrv; /* Physical drive number */ BYTE pdrv; /* Associated physical drive */
BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */ BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
@ -133,6 +133,9 @@ typedef struct {
DWORD fatbase; /* FAT base sector */ DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */ DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */ DWORD database; /* Data base sector */
#if FF_FS_EXFAT
DWORD bitbase; /* Allocation bitmap base sector */
#endif
DWORD winsect; /* Current sector appearing in the win[] */ DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS; } FATFS;
@ -145,7 +148,7 @@ typedef struct {
FATFS* fs; /* Pointer to the hosting volume of this object */ FATFS* fs; /* Pointer to the hosting volume of this object */
WORD id; /* Hosting volume mount ID */ WORD id; /* Hosting volume mount ID */
BYTE attr; /* Object attribute */ BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */ BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */ FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if FF_FS_EXFAT #if FF_FS_EXFAT

View file

@ -1,8 +1,8 @@
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ FatFs - Configuration file / FatFs Functional Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define FFCONF_DEF 63463 /* Revision ID */ #define FFCONF_DEF 86604 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Function Configurations / Function Configurations
@ -232,7 +232,7 @@
#define FF_FS_EXFAT 1 #define FF_FS_EXFAT 1
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
/ To enable exFAT, also LFN needs to be enabled. / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ / Note that enabling exFAT discards ANSI C (C89) compatibility. */
@ -262,6 +262,7 @@
/ lock control is independent of re-entrancy. */ / lock control is independent of re-entrancy. */
/* #include <somertos.h> // O/S definitions */
#define FF_FS_REENTRANT 0 #define FF_FS_REENTRANT 0
#define FF_FS_TIMEOUT 1000 #define FF_FS_TIMEOUT 1000
#define FF_SYNC_t HANDLE #define FF_SYNC_t HANDLE
@ -282,8 +283,6 @@
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */ / included somewhere in the scope of ff.h. */
/* #include <windows.h> // O/S definitions */
/*--- End of configuration options ---*/ /*--- End of configuration options ---*/

View file

@ -1,6 +1,6 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs */ /* Sample Code of OS Dependent Functions for FatFs */
/* (C) ChaN, 2017 */ /* (C) ChaN, 2018 */
/* (C) CTCaer, 2018 */ /* (C) CTCaer, 2018 */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
@ -16,7 +16,7 @@
/* Allocate a memory block */ /* Allocate a memory block */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
UINT msize /* Number of bytes to allocate */ UINT msize /* Number of bytes to allocate */
) )
{ {
@ -29,7 +29,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
void ff_memfree ( void ff_memfree (
void* mblock /* Pointer to the memory block to free (nothing to do for null) */ void* mblock /* Pointer to the memory block to free (nothing to do if null) */
) )
{ {
free(mblock); /* Free the memory block with POSIX API */ free(mblock); /* Free the memory block with POSIX API */

View file

@ -1,5 +1,5 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.13a */ /* Unicode handling functions for FatFs R0.13c */
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* This module will occupy a huge memory in the .const section when the / /* This module will occupy a huge memory in the .const section when the /
/ FatFs is configured for LFN with DBCS. If the system has any Unicode / / FatFs is configured for LFN with DBCS. If the system has any Unicode /
@ -7,7 +7,7 @@
/ that function to avoid silly memory consumption. / / that function to avoid silly memory consumption. /
/-------------------------------------------------------------------------*/ /-------------------------------------------------------------------------*/
/* /*
/ Copyright (C) 2017, ChaN, all right reserved. / Copyright (C) 2018, ChaN, all right reserved.
/ /
/ FatFs module is an open source software. Redistribution and use of FatFs in / FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided / source and binary forms, with or without modification, are permitted provided
@ -25,9 +25,9 @@
#include "ff.h" #include "ff.h"
#if FF_USE_LFN /* This module is blanked when non-LFN configuration */ #if FF_USE_LFN /* This module will be blanked at non-LFN configuration */
#if FF_DEFINED != 63463 /* Revision ID */ #if FF_DEFINED != 86604 /* Revision ID */
#error Wrong include file (ff.h). #error Wrong include file (ff.h).
#endif #endif