Fork of FATFileSystem that exposes FILINFO in the FATDirHandle. This allows obtaining true file sizes and testing whether a dir pointer is a directory or a file.

Dependents:   SDFileSystemNoStall

Fork of FATFileSystem by mbed official

Committer:
uci1
Date:
Thu Oct 30 07:01:15 2014 +0000
Revision:
6:7a3c53d25d96
Parent:
4:3ff2606d5713
Revert the fat file system back to that from 17 Mar 2014 so that it works with the SD card library, and add again the exposing of FILINFO to FATDirHandle

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 1:46ce1e16c870 1 /* mbed Microcontroller Library
emilmont 1:46ce1e16c870 2 * Copyright (c) 2006-2012 ARM Limited
emilmont 1:46ce1e16c870 3 *
emilmont 1:46ce1e16c870 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
emilmont 1:46ce1e16c870 5 * of this software and associated documentation files (the "Software"), to deal
emilmont 1:46ce1e16c870 6 * in the Software without restriction, including without limitation the rights
emilmont 1:46ce1e16c870 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
emilmont 1:46ce1e16c870 8 * copies of the Software, and to permit persons to whom the Software is
emilmont 1:46ce1e16c870 9 * furnished to do so, subject to the following conditions:
emilmont 1:46ce1e16c870 10 *
emilmont 1:46ce1e16c870 11 * The above copyright notice and this permission notice shall be included in
emilmont 1:46ce1e16c870 12 * all copies or substantial portions of the Software.
emilmont 1:46ce1e16c870 13 *
emilmont 1:46ce1e16c870 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
emilmont 1:46ce1e16c870 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
emilmont 1:46ce1e16c870 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
emilmont 1:46ce1e16c870 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
emilmont 1:46ce1e16c870 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
emilmont 1:46ce1e16c870 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
emilmont 1:46ce1e16c870 20 * SOFTWARE.
emilmont 1:46ce1e16c870 21 */
emilmont 1:46ce1e16c870 22 #include "mbed.h"
emilmont 1:46ce1e16c870 23
emilmont 1:46ce1e16c870 24 #include "ffconf.h"
emilmont 2:b6669c987c8e 25 #include "mbed_debug.h"
emilmont 1:46ce1e16c870 26
emilmont 1:46ce1e16c870 27 #include "FATFileSystem.h"
emilmont 1:46ce1e16c870 28 #include "FATFileHandle.h"
emilmont 1:46ce1e16c870 29 #include "FATDirHandle.h"
emilmont 1:46ce1e16c870 30
emilmont 1:46ce1e16c870 31 DWORD get_fattime(void) {
emilmont 1:46ce1e16c870 32 time_t rawtime;
emilmont 1:46ce1e16c870 33 time(&rawtime);
emilmont 1:46ce1e16c870 34 struct tm *ptm = localtime(&rawtime);
emilmont 1:46ce1e16c870 35 return (DWORD)(ptm->tm_year - 80) << 25
emilmont 1:46ce1e16c870 36 | (DWORD)(ptm->tm_mon + 1 ) << 21
emilmont 1:46ce1e16c870 37 | (DWORD)(ptm->tm_mday ) << 16
emilmont 1:46ce1e16c870 38 | (DWORD)(ptm->tm_hour ) << 11
emilmont 1:46ce1e16c870 39 | (DWORD)(ptm->tm_min ) << 5
emilmont 1:46ce1e16c870 40 | (DWORD)(ptm->tm_sec/2 );
emilmont 1:46ce1e16c870 41 }
emilmont 1:46ce1e16c870 42
emilmont 1:46ce1e16c870 43 FATFileSystem *FATFileSystem::_ffs[_VOLUMES] = {0};
emilmont 1:46ce1e16c870 44
emilmont 1:46ce1e16c870 45 FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n) {
emilmont 1:46ce1e16c870 46 debug_if(FFS_DBG, "FATFileSystem(%s)\n", n);
emilmont 1:46ce1e16c870 47 for(int i=0; i<_VOLUMES; i++) {
emilmont 1:46ce1e16c870 48 if(_ffs[i] == 0) {
emilmont 1:46ce1e16c870 49 _ffs[i] = this;
emilmont 1:46ce1e16c870 50 _fsid = i;
emilmont 1:46ce1e16c870 51 debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%d]\n", _name, _fsid);
emilmont 1:46ce1e16c870 52 f_mount(i, &_fs);
emilmont 1:46ce1e16c870 53 return;
emilmont 1:46ce1e16c870 54 }
emilmont 1:46ce1e16c870 55 }
emilmont 1:46ce1e16c870 56 error("Couldn't create %s in FATFileSystem::FATFileSystem\n", n);
emilmont 1:46ce1e16c870 57 }
emilmont 1:46ce1e16c870 58
emilmont 1:46ce1e16c870 59 FATFileSystem::~FATFileSystem() {
emilmont 1:46ce1e16c870 60 for (int i=0; i<_VOLUMES; i++) {
emilmont 1:46ce1e16c870 61 if (_ffs[i] == this) {
emilmont 1:46ce1e16c870 62 _ffs[i] = 0;
emilmont 1:46ce1e16c870 63 f_mount(i, NULL);
emilmont 1:46ce1e16c870 64 }
emilmont 1:46ce1e16c870 65 }
emilmont 1:46ce1e16c870 66 }
emilmont 1:46ce1e16c870 67
emilmont 1:46ce1e16c870 68 FileHandle *FATFileSystem::open(const char* name, int flags) {
emilmont 1:46ce1e16c870 69 debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%d]\n", name, _name, _fsid);
emilmont 1:46ce1e16c870 70 char n[64];
emilmont 1:46ce1e16c870 71 sprintf(n, "%d:/%s", _fsid, name);
uci1 6:7a3c53d25d96 72
emilmont 1:46ce1e16c870 73 /* POSIX flags -> FatFS open mode */
emilmont 1:46ce1e16c870 74 BYTE openmode;
emilmont 1:46ce1e16c870 75 if (flags & O_RDWR) {
emilmont 1:46ce1e16c870 76 openmode = FA_READ|FA_WRITE;
emilmont 1:46ce1e16c870 77 } else if(flags & O_WRONLY) {
emilmont 1:46ce1e16c870 78 openmode = FA_WRITE;
emilmont 1:46ce1e16c870 79 } else {
emilmont 1:46ce1e16c870 80 openmode = FA_READ;
emilmont 1:46ce1e16c870 81 }
emilmont 1:46ce1e16c870 82 if(flags & O_CREAT) {
emilmont 1:46ce1e16c870 83 if(flags & O_TRUNC) {
emilmont 1:46ce1e16c870 84 openmode |= FA_CREATE_ALWAYS;
emilmont 1:46ce1e16c870 85 } else {
emilmont 1:46ce1e16c870 86 openmode |= FA_OPEN_ALWAYS;
emilmont 1:46ce1e16c870 87 }
emilmont 1:46ce1e16c870 88 }
uci1 6:7a3c53d25d96 89
emilmont 1:46ce1e16c870 90 FIL fh;
emilmont 1:46ce1e16c870 91 FRESULT res = f_open(&fh, n, openmode);
uci1 6:7a3c53d25d96 92 if (res) {
emilmont 1:46ce1e16c870 93 debug_if(FFS_DBG, "f_open('w') failed: %d\n", res);
emilmont 1:46ce1e16c870 94 return NULL;
emilmont 1:46ce1e16c870 95 }
emilmont 1:46ce1e16c870 96 if (flags & O_APPEND) {
emilmont 1:46ce1e16c870 97 f_lseek(&fh, fh.fsize);
emilmont 1:46ce1e16c870 98 }
emilmont 1:46ce1e16c870 99 return new FATFileHandle(fh);
emilmont 1:46ce1e16c870 100 }
uci1 6:7a3c53d25d96 101
emilmont 1:46ce1e16c870 102 int FATFileSystem::remove(const char *filename) {
emilmont 1:46ce1e16c870 103 FRESULT res = f_unlink(filename);
uci1 6:7a3c53d25d96 104 if (res) {
emilmont 1:46ce1e16c870 105 debug_if(FFS_DBG, "f_unlink() failed: %d\n", res);
emilmont 1:46ce1e16c870 106 return -1;
emilmont 1:46ce1e16c870 107 }
emilmont 1:46ce1e16c870 108 return 0;
emilmont 1:46ce1e16c870 109 }
emilmont 1:46ce1e16c870 110
emilmont 1:46ce1e16c870 111 int FATFileSystem::format() {
emilmont 1:46ce1e16c870 112 FRESULT res = f_mkfs(_fsid, 0, 512); // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster)
emilmont 1:46ce1e16c870 113 if (res) {
emilmont 1:46ce1e16c870 114 debug_if(FFS_DBG, "f_mkfs() failed: %d\n", res);
emilmont 1:46ce1e16c870 115 return -1;
emilmont 1:46ce1e16c870 116 }
emilmont 1:46ce1e16c870 117 return 0;
emilmont 1:46ce1e16c870 118 }
emilmont 1:46ce1e16c870 119
emilmont 1:46ce1e16c870 120 DirHandle *FATFileSystem::opendir(const char *name) {
emilmont 1:46ce1e16c870 121 FATFS_DIR dir;
emilmont 1:46ce1e16c870 122 FRESULT res = f_opendir(&dir, name);
emilmont 1:46ce1e16c870 123 if (res != 0) {
emilmont 1:46ce1e16c870 124 return NULL;
emilmont 1:46ce1e16c870 125 }
emilmont 1:46ce1e16c870 126 return new FATDirHandle(dir);
emilmont 1:46ce1e16c870 127 }
emilmont 1:46ce1e16c870 128
emilmont 1:46ce1e16c870 129 int FATFileSystem::mkdir(const char *name, mode_t mode) {
emilmont 1:46ce1e16c870 130 FRESULT res = f_mkdir(name);
emilmont 1:46ce1e16c870 131 return res == 0 ? 0 : -1;
emilmont 1:46ce1e16c870 132 }