mirror of https://github.com/ARMmbed/mbed-os.git
FAT: Added support for block sizes of 512-4096 bytes
This is necessary for support of block devices with >512 byte blocks, such as most SPI flash parts. - Enabled support of up to 4096 byte blocks - Added support for heap-backed buffers using _FS_HEAPBUF - Necessary to avoid stack overflows - Avoids over-aggresive allocations of _MAX_SS - Enabled _FS_TINY to further reduce memory footprint - Haven't found a downside for this yet except for possible thread contentionpull/3972/head
parent
5f138810a9
commit
c0aa841ffd
|
@ -2249,6 +2249,13 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */
|
||||||
#if _MAX_SS != _MIN_SS /* Get sector size (multiple sector size cfg only) */
|
#if _MAX_SS != _MIN_SS /* Get sector size (multiple sector size cfg only) */
|
||||||
if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
|
if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
|
||||||
|| SS(fs) < _MIN_SS || SS(fs) > _MAX_SS) return FR_DISK_ERR;
|
|| SS(fs) < _MIN_SS || SS(fs) > _MAX_SS) return FR_DISK_ERR;
|
||||||
|
#endif
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
if (!fs->win) {
|
||||||
|
fs->win = (BYTE*)ff_memalloc(SS(fs)); /* Allocate buffer to back window if necessary */
|
||||||
|
if (!fs->win)
|
||||||
|
return FR_NOT_ENOUGH_CORE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */
|
/* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */
|
||||||
bsect = 0;
|
bsect = 0;
|
||||||
|
@ -2423,12 +2430,18 @@ FRESULT f_mount (
|
||||||
if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
|
if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
|
||||||
#endif
|
#endif
|
||||||
cfs->fs_type = 0; /* Clear old fs object */
|
cfs->fs_type = 0; /* Clear old fs object */
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
ff_memfree(cfs->win); /* Clean up window buffer */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs) {
|
if (fs) {
|
||||||
fs->fs_type = 0; /* Clear new fs object */
|
fs->fs_type = 0; /* Clear new fs object */
|
||||||
#if _FS_REENTRANT /* Create sync object for the new volume */
|
#if _FS_REENTRANT /* Create sync object for the new volume */
|
||||||
if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
|
if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
|
||||||
|
#endif
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
fs->win = 0; /* NULL buffer to prevent use of uninitialized buffer */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
FatFs[vol] = fs; /* Register new fs object */
|
FatFs[vol] = fs; /* Register new fs object */
|
||||||
|
@ -2570,6 +2583,11 @@ FRESULT f_open (
|
||||||
#endif
|
#endif
|
||||||
fp->fs = dj.fs; /* Validate file object */
|
fp->fs = dj.fs; /* Validate file object */
|
||||||
fp->id = fp->fs->id;
|
fp->id = fp->fs->id;
|
||||||
|
#if !_FS_TINY && _FS_HEAPBUF
|
||||||
|
fp->buf = (BYTE*)ff_memalloc(SS(dj.fs)); /* Allocate buffer if necessary */
|
||||||
|
if (!fp->buf)
|
||||||
|
return FR_NOT_ENOUGH_CORE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2892,6 +2910,9 @@ FRESULT f_close (
|
||||||
fp->fs = 0; /* Invalidate file object */
|
fp->fs = 0; /* Invalidate file object */
|
||||||
#if _FS_REENTRANT
|
#if _FS_REENTRANT
|
||||||
unlock_fs(fs, FR_OK); /* Unlock volume */
|
unlock_fs(fs, FR_OK); /* Unlock volume */
|
||||||
|
#endif
|
||||||
|
#if !_FS_TINY && _FS_HEAPBUF
|
||||||
|
ff_memfree(fp->buf); /* Deallocate buffer */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4112,6 +4133,13 @@ FRESULT f_mkfs (
|
||||||
#if _MAX_SS != _MIN_SS /* Get disk sector size */
|
#if _MAX_SS != _MIN_SS /* Get disk sector size */
|
||||||
if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS || SS(fs) < _MIN_SS)
|
if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS || SS(fs) < _MIN_SS)
|
||||||
return FR_DISK_ERR;
|
return FR_DISK_ERR;
|
||||||
|
#endif
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
if (!fs->win) {
|
||||||
|
fs->win = (BYTE*)ff_memalloc(SS(fs)); /* Allocate buffer to back window if necessary */
|
||||||
|
if (!fs->win)
|
||||||
|
return FR_NOT_ENOUGH_CORE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (_MULTI_PARTITION && part) {
|
if (_MULTI_PARTITION && part) {
|
||||||
/* Get partition information from partition table in the MBR */
|
/* Get partition information from partition table in the MBR */
|
||||||
|
|
|
@ -104,7 +104,11 @@ typedef struct {
|
||||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||||
DWORD database; /* Data start sector */
|
DWORD database; /* Data start sector */
|
||||||
DWORD winsect; /* Current sector appearing in the win[] */
|
DWORD winsect; /* Current sector appearing in the win[] */
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
BYTE *win; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
#else
|
||||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
#endif
|
||||||
} FATFS;
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,8 +136,12 @@ typedef struct {
|
||||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||||
#endif
|
#endif
|
||||||
#if !_FS_TINY
|
#if !_FS_TINY
|
||||||
|
#if _FS_HEAPBUF
|
||||||
|
BYTE *buf; /* File private data read/write window */
|
||||||
|
#else
|
||||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
} FIL;
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,14 +272,16 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||||
DWORD get_fattime (void);
|
DWORD get_fattime (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Memory functions */
|
||||||
|
#if _USE_LFN == 3 || _FS_HEAPBUF
|
||||||
|
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||||
|
void ff_memfree (void* mblock); /* Free memory block */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unicode support functions */
|
/* Unicode support functions */
|
||||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||||
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
|
||||||
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
|
||||||
#if _USE_LFN == 3 /* Memory functions */
|
|
||||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
|
||||||
void ff_memfree (void* mblock); /* Free memory block */
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Sync functions */
|
/* Sync functions */
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define _MIN_SS 512
|
#define _MIN_SS 512
|
||||||
#define _MAX_SS 512
|
#define _MAX_SS 4096
|
||||||
/* These options configure the range of sector size to be supported. (512, 1024,
|
/* These options configure the range of sector size to be supported. (512, 1024,
|
||||||
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
|
||||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||||
|
@ -194,7 +194,7 @@
|
||||||
/ System Configurations
|
/ System Configurations
|
||||||
/---------------------------------------------------------------------------*/
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define _FS_TINY 0
|
#define _FS_TINY 1
|
||||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
|
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
|
||||||
/ bytes. Instead of private sector buffer eliminated from the file object,
|
/ bytes. Instead of private sector buffer eliminated from the file object,
|
||||||
|
@ -202,6 +202,14 @@
|
||||||
/ data transfer. */
|
/ data transfer. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_HEAPBUF 1
|
||||||
|
/* This option enables the use of the heap for allocating buffers. Otherwise
|
||||||
|
/ _MAX_SS sized buffers are allocated statically in relevant structures (in
|
||||||
|
/ FATFS if _FS_TINY, otherwise in FATFS and FIL)
|
||||||
|
/ This option allows the filesystem to dynamically allocate the buffers based
|
||||||
|
/ on underlying sector size. */
|
||||||
|
|
||||||
|
|
||||||
#define _FS_NORTC 0
|
#define _FS_NORTC 0
|
||||||
#define _NORTC_MON 1
|
#define _NORTC_MON 1
|
||||||
#define _NORTC_MDAY 1
|
#define _NORTC_MDAY 1
|
||||||
|
|
|
@ -146,6 +146,16 @@ DWORD get_fattime(void)
|
||||||
| (DWORD)(ptm->tm_sec/2 );
|
| (DWORD)(ptm->tm_sec/2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *ff_memalloc(UINT size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_memfree(void *p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
// Implementation of diskio functions (see ChaN/diskio.h)
|
// Implementation of diskio functions (see ChaN/diskio.h)
|
||||||
DSTATUS disk_status(BYTE pdrv)
|
DSTATUS disk_status(BYTE pdrv)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue