Emilia Marino / SDFileSystem
Committer:
emiliamarino
Date:
Sat Dec 18 20:17:31 2021 +0000
Revision:
0:5f7b02d095c2
Assignment 4

Who changed what in which revision?

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