From 65602895a59f9e9c79ca65342ee3b843ba37183f Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Fri, 27 Jun 2014 06:10:18 +0200 Subject: [PATCH] FatFS complete implementation --- gfxconf.example.h | 1 + src/gfile/gfile.c | 32 +++++++++++++++++++++ src/gfile/inc_chibiosfs.c | 1 + src/gfile/inc_fatfs.c | 59 +++++++++++++++++++++++++++++---------- src/gfile/inc_memfs.c | 1 + src/gfile/inc_nativefs.c | 1 + src/gfile/inc_romfs.c | 1 + src/gfile/sys_defs.h | 32 +++++++++++++++++++++ src/gfile/sys_options.h | 12 ++++++++ 9 files changed, 126 insertions(+), 14 deletions(-) diff --git a/gfxconf.example.h b/gfxconf.example.h index f0dc2ca2..d1b5c2c8 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -219,6 +219,7 @@ // #define GFILE_ALLOW_FLOATS FALSE // #define GFILE_ALLOW_DEVICESPECIFIC FALSE // #define GFILE_MAX_GFILES 3 +//#define GFILE_NEED_AUTOMOUNT FALSE //#define GFILE_NEED_MEMFS FALSE //#define GFILE_NEED_ROMFS FALSE diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 7af27cbf..a410a801 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -56,6 +56,8 @@ typedef struct GFILEVMT { bool_t (*setpos) (GFILE *f, long int pos); long int (*getsize) (GFILE *f); bool_t (*eof) (GFILE *f); + bool_t (*mount) (const char *drive); + bool_t (*unmount) (const char *drive); } GFILEVMT; // The chain of FileSystems @@ -475,6 +477,36 @@ bool_t gfileEOF(GFILE *f) { return f->vmt->eof(f); } +#if GFILE_NEED_FATFS + bool_t gfileMount(char fs, const char* drive) { + const GFILEVMT *p; + + // Find the correct VMT + for(p = FsChain; p; p = p->next) { + if (p->prefix == fs) { + if (!p->mount) + return FALSE; + return p->mount(drive); + } + } + return FALSE; + } + + bool_t gfileUnmount(char fs, const char* drive) { + const GFILEVMT *p; + + // Find the correct VMT + for(p = FsChain; p; p = p->next) { + if (p->prefix == fs) { + if (!p->mount) + return FALSE; + return p->unmount(drive); + } + } + return FALSE; + } +#endif + /******************************************************** * String VMT routines ********************************************************/ diff --git a/src/gfile/inc_chibiosfs.c b/src/gfile/inc_chibiosfs.c index 87b8c110..92664288 100644 --- a/src/gfile/inc_chibiosfs.c +++ b/src/gfile/inc_chibiosfs.c @@ -27,6 +27,7 @@ static const GFILEVMT FsCHIBIOSVMT = { 0, 0, 0, 0, 0, ChibiOSBFSClose, ChibiOSBFSRead, ChibiOSBFSWrite, ChibiOSBFSSetpos, ChibiOSBFSGetsize, ChibiOSBFSEof, + 0, 0 }; static void ChibiOSBFSClose(GFILE *f) { diff --git a/src/gfile/inc_fatfs.c b/src/gfile/inc_fatfs.c index a3976d24..ff75eb3b 100644 --- a/src/gfile/inc_fatfs.c +++ b/src/gfile/inc_fatfs.c @@ -12,14 +12,6 @@ #include "ff.h" #include "ffconf.h" -/* - * ToDo: - * - * - f_mount has to be called before the disk can be accessed - * - complete _flags2mode() - * - restructure provided diskio.c files - */ - /******************************************************** * The FAT file-system VMT ********************************************************/ @@ -35,6 +27,8 @@ static int fatfsWrite(GFILE* f, const void* buf, int size); static bool_t fatfsSetPos(GFILE* f, long int pos); static long int fatfsGetSize(GFILE* f); static bool_t fatfsEOF(GFILE* f); +static bool_t fatfsMount(const char* drive); +static bool_t fatfsUnmount(const char* drive); static const GFILEVMT FsFatFSVMT = { GFILE_CHAINHEAD, @@ -50,12 +44,18 @@ static const GFILEVMT FsFatFSVMT = { fatfsWrite, fatfsSetPos, fatfsGetSize, - fatfsEOF + fatfsEOF, + fatfsMount, + fatfsUnmount }; #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsFatFSVMT +// optimize these later on. Use an array to have multiple FatFS +static bool_t fatfs_mounted = FALSE; +static FATFS fatfs_fs; + static void _flags2mode(GFILE* f, BYTE* mode) { *mode = 0; @@ -123,7 +123,10 @@ static bool_t fatfsOpen(GFILE* f, const char* fname) FIL* fd; BYTE mode; FRESULT ferr; - +/* + if (!fatfs_mounted && !fatfsMount("")) + return FALSE; +*/ if (!(fd = gfxAlloc(sizeof(FIL)))) return FALSE; @@ -131,7 +134,7 @@ static bool_t fatfsOpen(GFILE* f, const char* fname) ferr = f_open(fd, fname, mode); if (ferr != FR_OK) { - gfxFree( (FIL*)f->obj ); + gfxFree(fd); f->obj = 0; return FALSE; @@ -144,10 +147,10 @@ static bool_t fatfsOpen(GFILE* f, const char* fname) static void fatfsClose(GFILE* f) { - if ((FIL*)f->obj != 0) + if ((FIL*)f->obj != 0) { gfxFree( (FIL*)f->obj ); - - f_close( (FIL*)f->obj ); + f_close( (FIL*)f->obj ); + } } static int fatfsRead(GFILE* f, void* buf, int size) @@ -192,3 +195,31 @@ static bool_t fatfsEOF(GFILE* f) return FALSE; } +static bool_t fatfsMount(const char* drive) +{ + FRESULT ferr; + + if (!fatfs_mounted) { + ferr = f_mount(&fatfs_fs, drive, 1); + if (ferr != FR_OK) + return FALSE; + fatfs_mounted = TRUE; + return TRUE; + } + + return FALSE; +} + +static bool_t fatfsUnmount(const char* drive) +{ + (void)drive; + + if (fatfs_mounted) { + // FatFS does not provide an unmount routine. + fatfs_mounted = FALSE; + return TRUE; + } + + return FALSE; +} + diff --git a/src/gfile/inc_memfs.c b/src/gfile/inc_memfs.c index 434150d8..c7322686 100644 --- a/src/gfile/inc_memfs.c +++ b/src/gfile/inc_memfs.c @@ -26,6 +26,7 @@ static const GFILEVMT FsMemVMT = { 0, 0, 0, 0, 0, 0, MEMRead, MEMWrite, MEMSetpos, 0, 0, + 0, 0 }; static int MEMRead(GFILE *f, void *buf, int size) { diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index 4ecb2004..26dc33c5 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -46,6 +46,7 @@ static const GFILEVMT FsNativeVMT = { NativeDel, NativeExists, NativeFilesize, NativeRen, NativeOpen, NativeClose, NativeRead, NativeWrite, NativeSetpos, NativeGetsize, NativeEof, + 0, 0 }; #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsNativeVMT diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 3510a261..9f7faf7c 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -52,6 +52,7 @@ static const GFILEVMT FsROMVMT = { 0, ROMExists, ROMFilesize, 0, ROMOpen, ROMClose, ROMRead, 0, ROMSetpos, ROMGetsize, ROMEof, + 0, 0 }; #undef GFILE_CHAINHEAD #define GFILE_CHAINHEAD &FsROMVMT diff --git a/src/gfile/sys_defs.h b/src/gfile/sys_defs.h index e4bced67..cf5235d2 100644 --- a/src/gfile/sys_defs.h +++ b/src/gfile/sys_defs.h @@ -200,10 +200,42 @@ extern "C" { #if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode); #endif + #if GFILE_NEED_MEMFS GFILE * gfileOpenMemory(void *memptr, const char *mode); #endif + #if GFILE_NEED_FATFS + /** + * @brief Mount a logical drive (aka partition) + * + * @details Not supported by every file system + * @details Currently just one drive at one is supported. + * + * @param[in] fs The file system (F for FatFS) + * @param[in] drive The logical drive prefix + * + * @return TRUE on success, FALSE otherwise + * + * @api + */ + bool_t gfileMount(char fs, const char *drive); + + /** + * @brief Unmount a logical drive (aka partition) + * + * @details Does have no effect if @p gfileMount() as been called before hand + * + * @param[in] fs The file system (F for FatFS) + * @param[in] drive The logical drive prefix + * + * @return TRUE on success, FALSE otherwise + * + * @api + */ + bool_t gfileUnmount(char fs, const char *drive); + #endif + #if GFILE_NEED_PRINTG #include diff --git a/src/gfile/sys_options.h b/src/gfile/sys_options.h index 564cc2d7..71eb6611 100644 --- a/src/gfile/sys_options.h +++ b/src/gfile/sys_options.h @@ -20,6 +20,18 @@ * @name GFILE Functionality to be included * @{ */ + /** + * @brief Should the filesystem be mounted automatically + * @details The filesystem will be mounted automatically if the + * user does not do it manually. + * @details Defaults to FALSE + * + * @note Only available for filesystems that actually implement a + * mounting routine. + */ + #ifndef GFILE_NEED_AUTOMOUNT + #define GFILE_NEED_AUTOMOUNT FALSE + #endif /** * @brief Include printg, fprintg etc functions * @details Defaults to FALSE