Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-os/features/filesystem/fat/FATFileSystem.cpp@0:fb8047b156bb, 2020-01-15 (annotated)
- Committer:
- rahul_dahiya
- Date:
- Wed Jan 15 15:57:15 2020 +0530
- Revision:
- 0:fb8047b156bb
STM32F7 LWIP
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rahul_dahiya |
0:fb8047b156bb | 1 | /* mbed Microcontroller Library |
rahul_dahiya |
0:fb8047b156bb | 2 | * Copyright (c) 2006-2012 ARM Limited |
rahul_dahiya |
0:fb8047b156bb | 3 | * |
rahul_dahiya |
0:fb8047b156bb | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
rahul_dahiya |
0:fb8047b156bb | 5 | * of this software and associated documentation files (the "Software"), to deal |
rahul_dahiya |
0:fb8047b156bb | 6 | * in the Software without restriction, including without limitation the rights |
rahul_dahiya |
0:fb8047b156bb | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
rahul_dahiya |
0:fb8047b156bb | 8 | * copies of the Software, and to permit persons to whom the Software is |
rahul_dahiya |
0:fb8047b156bb | 9 | * furnished to do so, subject to the following conditions: |
rahul_dahiya |
0:fb8047b156bb | 10 | * |
rahul_dahiya |
0:fb8047b156bb | 11 | * The above copyright notice and this permission notice shall be included in |
rahul_dahiya |
0:fb8047b156bb | 12 | * all copies or substantial portions of the Software. |
rahul_dahiya |
0:fb8047b156bb | 13 | * |
rahul_dahiya |
0:fb8047b156bb | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
rahul_dahiya |
0:fb8047b156bb | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
rahul_dahiya |
0:fb8047b156bb | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
rahul_dahiya |
0:fb8047b156bb | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
rahul_dahiya |
0:fb8047b156bb | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
rahul_dahiya |
0:fb8047b156bb | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
rahul_dahiya |
0:fb8047b156bb | 20 | * SOFTWARE. |
rahul_dahiya |
0:fb8047b156bb | 21 | */ |
rahul_dahiya |
0:fb8047b156bb | 22 | #include "mbed.h" |
rahul_dahiya |
0:fb8047b156bb | 23 | |
rahul_dahiya |
0:fb8047b156bb | 24 | #include "diskio.h" |
rahul_dahiya |
0:fb8047b156bb | 25 | #include "ffconf.h" |
rahul_dahiya |
0:fb8047b156bb | 26 | #include "mbed_debug.h" |
rahul_dahiya |
0:fb8047b156bb | 27 | #include "mbed_critical.h" |
rahul_dahiya |
0:fb8047b156bb | 28 | #include <errno.h> |
rahul_dahiya |
0:fb8047b156bb | 29 | |
rahul_dahiya |
0:fb8047b156bb | 30 | #include "FATFileSystem.h" |
rahul_dahiya |
0:fb8047b156bb | 31 | |
rahul_dahiya |
0:fb8047b156bb | 32 | |
rahul_dahiya |
0:fb8047b156bb | 33 | ////// Error handling ///// |
rahul_dahiya |
0:fb8047b156bb | 34 | |
rahul_dahiya |
0:fb8047b156bb | 35 | static int fat_error_remap(FRESULT res) |
rahul_dahiya |
0:fb8047b156bb | 36 | { |
rahul_dahiya |
0:fb8047b156bb | 37 | switch(res) { |
rahul_dahiya |
0:fb8047b156bb | 38 | case FR_OK: /* (0) Succeeded */ |
rahul_dahiya |
0:fb8047b156bb | 39 | return 0; /* no error */ |
rahul_dahiya |
0:fb8047b156bb | 40 | case FR_DISK_ERR: /* (1) A hard error occurred in the low level disk I/O layer */ |
rahul_dahiya |
0:fb8047b156bb | 41 | case FR_NOT_READY: /* (3) The physical drive cannot work */ |
rahul_dahiya |
0:fb8047b156bb | 42 | return -EIO; /* I/O error */ |
rahul_dahiya |
0:fb8047b156bb | 43 | case FR_NO_FILE: /* (4) Could not find the file */ |
rahul_dahiya |
0:fb8047b156bb | 44 | case FR_NO_PATH: /* (5) Could not find the path */ |
rahul_dahiya |
0:fb8047b156bb | 45 | case FR_INVALID_NAME: /* (6) The path name format is invalid */ |
rahul_dahiya |
0:fb8047b156bb | 46 | case FR_INVALID_DRIVE: /* (11) The logical drive number is invalid */ |
rahul_dahiya |
0:fb8047b156bb | 47 | case FR_NO_FILESYSTEM: /* (13) There is no valid FAT volume */ |
rahul_dahiya |
0:fb8047b156bb | 48 | return -ENOENT; /* No such file or directory */ |
rahul_dahiya |
0:fb8047b156bb | 49 | case FR_DENIED: /* (7) Access denied due to prohibited access or directory full */ |
rahul_dahiya |
0:fb8047b156bb | 50 | return -EACCES; /* Permission denied */ |
rahul_dahiya |
0:fb8047b156bb | 51 | case FR_EXIST: /* (8) Access denied due to prohibited access */ |
rahul_dahiya |
0:fb8047b156bb | 52 | return -EEXIST; /* File exists */ |
rahul_dahiya |
0:fb8047b156bb | 53 | case FR_WRITE_PROTECTED: /* (10) The physical drive is write protected */ |
rahul_dahiya |
0:fb8047b156bb | 54 | case FR_LOCKED: /* (16) The operation is rejected according to the file sharing policy */ |
rahul_dahiya |
0:fb8047b156bb | 55 | return -EACCES; /* Permission denied */ |
rahul_dahiya |
0:fb8047b156bb | 56 | case FR_INVALID_OBJECT: /* (9) The file/directory object is invalid */ |
rahul_dahiya |
0:fb8047b156bb | 57 | return -EFAULT; /* Bad address */ |
rahul_dahiya |
0:fb8047b156bb | 58 | case FR_NOT_ENABLED: /* (12) The volume has no work area */ |
rahul_dahiya |
0:fb8047b156bb | 59 | return -ENXIO; /* No such device or address */ |
rahul_dahiya |
0:fb8047b156bb | 60 | case FR_NOT_ENOUGH_CORE: /* (17) LFN working buffer could not be allocated */ |
rahul_dahiya |
0:fb8047b156bb | 61 | return -ENOMEM; /* Not enough space */ |
rahul_dahiya |
0:fb8047b156bb | 62 | case FR_TOO_MANY_OPEN_FILES: /* (18) Number of open files > _FS_LOCK */ |
rahul_dahiya |
0:fb8047b156bb | 63 | return -ENFILE; /* Too many open files in system */ |
rahul_dahiya |
0:fb8047b156bb | 64 | case FR_INVALID_PARAMETER: /* (19) Given parameter is invalid */ |
rahul_dahiya |
0:fb8047b156bb | 65 | return -ENOEXEC; /* Exec format error */ |
rahul_dahiya |
0:fb8047b156bb | 66 | case FR_INT_ERR: /* (2) Assertion failed */ |
rahul_dahiya |
0:fb8047b156bb | 67 | case FR_MKFS_ABORTED: /* (14) The f_mkfs() aborted due to any parameter error */ |
rahul_dahiya |
0:fb8047b156bb | 68 | case FR_TIMEOUT: /* (15) Could not get a grant to access the volume within defined period */ |
rahul_dahiya |
0:fb8047b156bb | 69 | default: /* Bad file number */ |
rahul_dahiya |
0:fb8047b156bb | 70 | return -EBADF; |
rahul_dahiya |
0:fb8047b156bb | 71 | } |
rahul_dahiya |
0:fb8047b156bb | 72 | } |
rahul_dahiya |
0:fb8047b156bb | 73 | |
rahul_dahiya |
0:fb8047b156bb | 74 | // Helper class for deferring operations when variable falls out of scope |
rahul_dahiya |
0:fb8047b156bb | 75 | template <typename T> |
rahul_dahiya |
0:fb8047b156bb | 76 | class Deferred { |
rahul_dahiya |
0:fb8047b156bb | 77 | public: |
rahul_dahiya |
0:fb8047b156bb | 78 | T _t; |
rahul_dahiya |
0:fb8047b156bb | 79 | Callback<void(T)> _ondefer; |
rahul_dahiya |
0:fb8047b156bb | 80 | |
rahul_dahiya |
0:fb8047b156bb | 81 | Deferred(const Deferred&); |
rahul_dahiya |
0:fb8047b156bb | 82 | Deferred &operator=(const Deferred&); |
rahul_dahiya |
0:fb8047b156bb | 83 | |
rahul_dahiya |
0:fb8047b156bb | 84 | public: |
rahul_dahiya |
0:fb8047b156bb | 85 | Deferred(T t, Callback<void(T)> ondefer = NULL) |
rahul_dahiya |
0:fb8047b156bb | 86 | : _t(t), _ondefer(ondefer) |
rahul_dahiya |
0:fb8047b156bb | 87 | { |
rahul_dahiya |
0:fb8047b156bb | 88 | } |
rahul_dahiya |
0:fb8047b156bb | 89 | |
rahul_dahiya |
0:fb8047b156bb | 90 | operator T() |
rahul_dahiya |
0:fb8047b156bb | 91 | { |
rahul_dahiya |
0:fb8047b156bb | 92 | return _t; |
rahul_dahiya |
0:fb8047b156bb | 93 | } |
rahul_dahiya |
0:fb8047b156bb | 94 | |
rahul_dahiya |
0:fb8047b156bb | 95 | ~Deferred() |
rahul_dahiya |
0:fb8047b156bb | 96 | { |
rahul_dahiya |
0:fb8047b156bb | 97 | if (_ondefer) { |
rahul_dahiya |
0:fb8047b156bb | 98 | _ondefer(_t); |
rahul_dahiya |
0:fb8047b156bb | 99 | } |
rahul_dahiya |
0:fb8047b156bb | 100 | } |
rahul_dahiya |
0:fb8047b156bb | 101 | }; |
rahul_dahiya |
0:fb8047b156bb | 102 | |
rahul_dahiya |
0:fb8047b156bb | 103 | static void dodelete(const char *data) |
rahul_dahiya |
0:fb8047b156bb | 104 | { |
rahul_dahiya |
0:fb8047b156bb | 105 | delete[] data; |
rahul_dahiya |
0:fb8047b156bb | 106 | } |
rahul_dahiya |
0:fb8047b156bb | 107 | |
rahul_dahiya |
0:fb8047b156bb | 108 | // Adds prefix needed internally by fatfs, this can be avoided for the first fatfs |
rahul_dahiya |
0:fb8047b156bb | 109 | // (id 0) otherwise a prefix of "id:/" is inserted in front of the string. |
rahul_dahiya |
0:fb8047b156bb | 110 | static Deferred<const char*> fat_path_prefix(int id, const char *path) |
rahul_dahiya |
0:fb8047b156bb | 111 | { |
rahul_dahiya |
0:fb8047b156bb | 112 | // We can avoid dynamic allocation when only on fatfs is in use |
rahul_dahiya |
0:fb8047b156bb | 113 | if (id == 0) { |
rahul_dahiya |
0:fb8047b156bb | 114 | return path; |
rahul_dahiya |
0:fb8047b156bb | 115 | } |
rahul_dahiya |
0:fb8047b156bb | 116 | |
rahul_dahiya |
0:fb8047b156bb | 117 | // Prefix path with id, will look something like 2:/hi/hello/filehere.txt |
rahul_dahiya |
0:fb8047b156bb | 118 | char *buffer = new char[strlen("0:/") + strlen(path) + 1]; |
rahul_dahiya |
0:fb8047b156bb | 119 | if (!buffer) { |
rahul_dahiya |
0:fb8047b156bb | 120 | return NULL; |
rahul_dahiya |
0:fb8047b156bb | 121 | } |
rahul_dahiya |
0:fb8047b156bb | 122 | |
rahul_dahiya |
0:fb8047b156bb | 123 | buffer[0] = '0' + id; |
rahul_dahiya |
0:fb8047b156bb | 124 | buffer[1] = ':'; |
rahul_dahiya |
0:fb8047b156bb | 125 | buffer[2] = '/'; |
rahul_dahiya |
0:fb8047b156bb | 126 | strcpy(buffer + strlen("0:/"), path); |
rahul_dahiya |
0:fb8047b156bb | 127 | return Deferred<const char*>(buffer, dodelete); |
rahul_dahiya |
0:fb8047b156bb | 128 | } |
rahul_dahiya |
0:fb8047b156bb | 129 | |
rahul_dahiya |
0:fb8047b156bb | 130 | |
rahul_dahiya |
0:fb8047b156bb | 131 | ////// Disk operations ////// |
rahul_dahiya |
0:fb8047b156bb | 132 | |
rahul_dahiya |
0:fb8047b156bb | 133 | // Global access to block device from FAT driver |
rahul_dahiya |
0:fb8047b156bb | 134 | static BlockDevice *_ffs[_VOLUMES] = {0}; |
rahul_dahiya |
0:fb8047b156bb | 135 | static SingletonPtr<PlatformMutex> _ffs_mutex; |
rahul_dahiya |
0:fb8047b156bb | 136 | |
rahul_dahiya |
0:fb8047b156bb | 137 | |
rahul_dahiya |
0:fb8047b156bb | 138 | // FAT driver functions |
rahul_dahiya |
0:fb8047b156bb | 139 | DWORD get_fattime(void) |
rahul_dahiya |
0:fb8047b156bb | 140 | { |
rahul_dahiya |
0:fb8047b156bb | 141 | time_t rawtime; |
rahul_dahiya |
0:fb8047b156bb | 142 | time(&rawtime); |
rahul_dahiya |
0:fb8047b156bb | 143 | struct tm *ptm = localtime(&rawtime); |
rahul_dahiya |
0:fb8047b156bb | 144 | return (DWORD)(ptm->tm_year - 80) << 25 |
rahul_dahiya |
0:fb8047b156bb | 145 | | (DWORD)(ptm->tm_mon + 1 ) << 21 |
rahul_dahiya |
0:fb8047b156bb | 146 | | (DWORD)(ptm->tm_mday ) << 16 |
rahul_dahiya |
0:fb8047b156bb | 147 | | (DWORD)(ptm->tm_hour ) << 11 |
rahul_dahiya |
0:fb8047b156bb | 148 | | (DWORD)(ptm->tm_min ) << 5 |
rahul_dahiya |
0:fb8047b156bb | 149 | | (DWORD)(ptm->tm_sec/2 ); |
rahul_dahiya |
0:fb8047b156bb | 150 | } |
rahul_dahiya |
0:fb8047b156bb | 151 | |
rahul_dahiya |
0:fb8047b156bb | 152 | void *ff_memalloc(UINT size) |
rahul_dahiya |
0:fb8047b156bb | 153 | { |
rahul_dahiya |
0:fb8047b156bb | 154 | return malloc(size); |
rahul_dahiya |
0:fb8047b156bb | 155 | } |
rahul_dahiya |
0:fb8047b156bb | 156 | |
rahul_dahiya |
0:fb8047b156bb | 157 | void ff_memfree(void *p) |
rahul_dahiya |
0:fb8047b156bb | 158 | { |
rahul_dahiya |
0:fb8047b156bb | 159 | free(p); |
rahul_dahiya |
0:fb8047b156bb | 160 | } |
rahul_dahiya |
0:fb8047b156bb | 161 | |
rahul_dahiya |
0:fb8047b156bb | 162 | // Implementation of diskio functions (see ChaN/diskio.h) |
rahul_dahiya |
0:fb8047b156bb | 163 | static WORD disk_get_sector_size(BYTE pdrv) |
rahul_dahiya |
0:fb8047b156bb | 164 | { |
rahul_dahiya |
0:fb8047b156bb | 165 | WORD ssize = _ffs[pdrv]->get_erase_size(); |
rahul_dahiya |
0:fb8047b156bb | 166 | if (ssize < 512) { |
rahul_dahiya |
0:fb8047b156bb | 167 | ssize = 512; |
rahul_dahiya |
0:fb8047b156bb | 168 | } |
rahul_dahiya |
0:fb8047b156bb | 169 | |
rahul_dahiya |
0:fb8047b156bb | 170 | MBED_ASSERT(ssize >= _MIN_SS && ssize <= _MAX_SS); |
rahul_dahiya |
0:fb8047b156bb | 171 | MBED_ASSERT(_ffs[pdrv]->get_read_size() <= _ffs[pdrv]->get_erase_size()); |
rahul_dahiya |
0:fb8047b156bb | 172 | MBED_ASSERT(_ffs[pdrv]->get_program_size() <= _ffs[pdrv]->get_erase_size()); |
rahul_dahiya |
0:fb8047b156bb | 173 | return ssize; |
rahul_dahiya |
0:fb8047b156bb | 174 | } |
rahul_dahiya |
0:fb8047b156bb | 175 | |
rahul_dahiya |
0:fb8047b156bb | 176 | static DWORD disk_get_sector_count(BYTE pdrv) |
rahul_dahiya |
0:fb8047b156bb | 177 | { |
rahul_dahiya |
0:fb8047b156bb | 178 | DWORD scount = _ffs[pdrv]->size() / disk_get_sector_size(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 179 | MBED_ASSERT(scount >= 64); |
rahul_dahiya |
0:fb8047b156bb | 180 | return scount; |
rahul_dahiya |
0:fb8047b156bb | 181 | } |
rahul_dahiya |
0:fb8047b156bb | 182 | |
rahul_dahiya |
0:fb8047b156bb | 183 | DSTATUS disk_status(BYTE pdrv) |
rahul_dahiya |
0:fb8047b156bb | 184 | { |
rahul_dahiya |
0:fb8047b156bb | 185 | debug_if(FFS_DBG, "disk_status on pdrv [%d]\n", pdrv); |
rahul_dahiya |
0:fb8047b156bb | 186 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 187 | } |
rahul_dahiya |
0:fb8047b156bb | 188 | |
rahul_dahiya |
0:fb8047b156bb | 189 | DSTATUS disk_initialize(BYTE pdrv) |
rahul_dahiya |
0:fb8047b156bb | 190 | { |
rahul_dahiya |
0:fb8047b156bb | 191 | debug_if(FFS_DBG, "disk_initialize on pdrv [%d]\n", pdrv); |
rahul_dahiya |
0:fb8047b156bb | 192 | return (DSTATUS)_ffs[pdrv]->init(); |
rahul_dahiya |
0:fb8047b156bb | 193 | } |
rahul_dahiya |
0:fb8047b156bb | 194 | |
rahul_dahiya |
0:fb8047b156bb | 195 | DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) |
rahul_dahiya |
0:fb8047b156bb | 196 | { |
rahul_dahiya |
0:fb8047b156bb | 197 | debug_if(FFS_DBG, "disk_read(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv); |
rahul_dahiya |
0:fb8047b156bb | 198 | DWORD ssize = disk_get_sector_size(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 199 | int err = _ffs[pdrv]->read(buff, sector*ssize, count*ssize); |
rahul_dahiya |
0:fb8047b156bb | 200 | return err ? RES_PARERR : RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 201 | } |
rahul_dahiya |
0:fb8047b156bb | 202 | |
rahul_dahiya |
0:fb8047b156bb | 203 | DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) |
rahul_dahiya |
0:fb8047b156bb | 204 | { |
rahul_dahiya |
0:fb8047b156bb | 205 | debug_if(FFS_DBG, "disk_write(sector %d, count %d) on pdrv [%d]\n", sector, count, pdrv); |
rahul_dahiya |
0:fb8047b156bb | 206 | DWORD ssize = disk_get_sector_size(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 207 | int err = _ffs[pdrv]->erase(sector*ssize, count*ssize); |
rahul_dahiya |
0:fb8047b156bb | 208 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 209 | return RES_PARERR; |
rahul_dahiya |
0:fb8047b156bb | 210 | } |
rahul_dahiya |
0:fb8047b156bb | 211 | |
rahul_dahiya |
0:fb8047b156bb | 212 | err = _ffs[pdrv]->program(buff, sector*ssize, count*ssize); |
rahul_dahiya |
0:fb8047b156bb | 213 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 214 | return RES_PARERR; |
rahul_dahiya |
0:fb8047b156bb | 215 | } |
rahul_dahiya |
0:fb8047b156bb | 216 | |
rahul_dahiya |
0:fb8047b156bb | 217 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 218 | } |
rahul_dahiya |
0:fb8047b156bb | 219 | |
rahul_dahiya |
0:fb8047b156bb | 220 | DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) |
rahul_dahiya |
0:fb8047b156bb | 221 | { |
rahul_dahiya |
0:fb8047b156bb | 222 | debug_if(FFS_DBG, "disk_ioctl(%d)\n", cmd); |
rahul_dahiya |
0:fb8047b156bb | 223 | switch (cmd) { |
rahul_dahiya |
0:fb8047b156bb | 224 | case CTRL_SYNC: |
rahul_dahiya |
0:fb8047b156bb | 225 | if (_ffs[pdrv] == NULL) { |
rahul_dahiya |
0:fb8047b156bb | 226 | return RES_NOTRDY; |
rahul_dahiya |
0:fb8047b156bb | 227 | } else { |
rahul_dahiya |
0:fb8047b156bb | 228 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 229 | } |
rahul_dahiya |
0:fb8047b156bb | 230 | case GET_SECTOR_COUNT: |
rahul_dahiya |
0:fb8047b156bb | 231 | if (_ffs[pdrv] == NULL) { |
rahul_dahiya |
0:fb8047b156bb | 232 | return RES_NOTRDY; |
rahul_dahiya |
0:fb8047b156bb | 233 | } else { |
rahul_dahiya |
0:fb8047b156bb | 234 | *((DWORD*)buff) = disk_get_sector_count(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 235 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 236 | } |
rahul_dahiya |
0:fb8047b156bb | 237 | case GET_SECTOR_SIZE: |
rahul_dahiya |
0:fb8047b156bb | 238 | if (_ffs[pdrv] == NULL) { |
rahul_dahiya |
0:fb8047b156bb | 239 | return RES_NOTRDY; |
rahul_dahiya |
0:fb8047b156bb | 240 | } else { |
rahul_dahiya |
0:fb8047b156bb | 241 | *((WORD*)buff) = disk_get_sector_size(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 242 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 243 | } |
rahul_dahiya |
0:fb8047b156bb | 244 | case GET_BLOCK_SIZE: |
rahul_dahiya |
0:fb8047b156bb | 245 | *((DWORD*)buff) = 1; // default when not known |
rahul_dahiya |
0:fb8047b156bb | 246 | return RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 247 | case CTRL_TRIM: |
rahul_dahiya |
0:fb8047b156bb | 248 | if (_ffs[pdrv] == NULL) { |
rahul_dahiya |
0:fb8047b156bb | 249 | return RES_NOTRDY; |
rahul_dahiya |
0:fb8047b156bb | 250 | } else { |
rahul_dahiya |
0:fb8047b156bb | 251 | DWORD *sectors = (DWORD*)buff; |
rahul_dahiya |
0:fb8047b156bb | 252 | DWORD ssize = disk_get_sector_size(pdrv); |
rahul_dahiya |
0:fb8047b156bb | 253 | int err = _ffs[pdrv]->trim(sectors[0]*ssize, (sectors[1]-sectors[0]+1)*ssize); |
rahul_dahiya |
0:fb8047b156bb | 254 | return err ? RES_PARERR : RES_OK; |
rahul_dahiya |
0:fb8047b156bb | 255 | } |
rahul_dahiya |
0:fb8047b156bb | 256 | } |
rahul_dahiya |
0:fb8047b156bb | 257 | |
rahul_dahiya |
0:fb8047b156bb | 258 | return RES_PARERR; |
rahul_dahiya |
0:fb8047b156bb | 259 | } |
rahul_dahiya |
0:fb8047b156bb | 260 | |
rahul_dahiya |
0:fb8047b156bb | 261 | |
rahul_dahiya |
0:fb8047b156bb | 262 | ////// Generic filesystem operations ////// |
rahul_dahiya |
0:fb8047b156bb | 263 | |
rahul_dahiya |
0:fb8047b156bb | 264 | // Filesystem implementation (See FATFilySystem.h) |
rahul_dahiya |
0:fb8047b156bb | 265 | FATFileSystem::FATFileSystem(const char *name, BlockDevice *bd) |
rahul_dahiya |
0:fb8047b156bb | 266 | : FileSystem(name), _id(-1) { |
rahul_dahiya |
0:fb8047b156bb | 267 | if (bd) { |
rahul_dahiya |
0:fb8047b156bb | 268 | mount(bd); |
rahul_dahiya |
0:fb8047b156bb | 269 | } |
rahul_dahiya |
0:fb8047b156bb | 270 | } |
rahul_dahiya |
0:fb8047b156bb | 271 | |
rahul_dahiya |
0:fb8047b156bb | 272 | FATFileSystem::~FATFileSystem() |
rahul_dahiya |
0:fb8047b156bb | 273 | { |
rahul_dahiya |
0:fb8047b156bb | 274 | // nop if unmounted |
rahul_dahiya |
0:fb8047b156bb | 275 | unmount(); |
rahul_dahiya |
0:fb8047b156bb | 276 | } |
rahul_dahiya |
0:fb8047b156bb | 277 | |
rahul_dahiya |
0:fb8047b156bb | 278 | int FATFileSystem::mount(BlockDevice *bd) { |
rahul_dahiya |
0:fb8047b156bb | 279 | // requires duplicate definition to allow virtual overload to work |
rahul_dahiya |
0:fb8047b156bb | 280 | return mount(bd, true); |
rahul_dahiya |
0:fb8047b156bb | 281 | } |
rahul_dahiya |
0:fb8047b156bb | 282 | |
rahul_dahiya |
0:fb8047b156bb | 283 | int FATFileSystem::mount(BlockDevice *bd, bool mount) { |
rahul_dahiya |
0:fb8047b156bb | 284 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 285 | if (_id != -1) { |
rahul_dahiya |
0:fb8047b156bb | 286 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 287 | return -EINVAL; |
rahul_dahiya |
0:fb8047b156bb | 288 | } |
rahul_dahiya |
0:fb8047b156bb | 289 | |
rahul_dahiya |
0:fb8047b156bb | 290 | for (int i = 0; i < _VOLUMES; i++) { |
rahul_dahiya |
0:fb8047b156bb | 291 | if (!_ffs[i]) { |
rahul_dahiya |
0:fb8047b156bb | 292 | _id = i; |
rahul_dahiya |
0:fb8047b156bb | 293 | _ffs[_id] = bd; |
rahul_dahiya |
0:fb8047b156bb | 294 | _fsid[0] = '0' + _id; |
rahul_dahiya |
0:fb8047b156bb | 295 | _fsid[1] = ':'; |
rahul_dahiya |
0:fb8047b156bb | 296 | _fsid[2] = '\0'; |
rahul_dahiya |
0:fb8047b156bb | 297 | debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", getName(), _fsid); |
rahul_dahiya |
0:fb8047b156bb | 298 | FRESULT res = f_mount(&_fs, _fsid, mount); |
rahul_dahiya |
0:fb8047b156bb | 299 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 300 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 301 | } |
rahul_dahiya |
0:fb8047b156bb | 302 | } |
rahul_dahiya |
0:fb8047b156bb | 303 | |
rahul_dahiya |
0:fb8047b156bb | 304 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 305 | return -ENOMEM; |
rahul_dahiya |
0:fb8047b156bb | 306 | } |
rahul_dahiya |
0:fb8047b156bb | 307 | |
rahul_dahiya |
0:fb8047b156bb | 308 | int FATFileSystem::unmount() |
rahul_dahiya |
0:fb8047b156bb | 309 | { |
rahul_dahiya |
0:fb8047b156bb | 310 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 311 | if (_id == -1) { |
rahul_dahiya |
0:fb8047b156bb | 312 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 313 | return -EINVAL; |
rahul_dahiya |
0:fb8047b156bb | 314 | } |
rahul_dahiya |
0:fb8047b156bb | 315 | |
rahul_dahiya |
0:fb8047b156bb | 316 | FRESULT res = f_mount(NULL, _fsid, 0); |
rahul_dahiya |
0:fb8047b156bb | 317 | _ffs[_id] = NULL; |
rahul_dahiya |
0:fb8047b156bb | 318 | _id = -1; |
rahul_dahiya |
0:fb8047b156bb | 319 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 320 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 321 | } |
rahul_dahiya |
0:fb8047b156bb | 322 | |
rahul_dahiya |
0:fb8047b156bb | 323 | /* See http://elm-chan.org/fsw/ff/en/mkfs.html for details of f_mkfs() and |
rahul_dahiya |
0:fb8047b156bb | 324 | * associated arguments. */ |
rahul_dahiya |
0:fb8047b156bb | 325 | int FATFileSystem::format(BlockDevice *bd, bd_size_t cluster_size) { |
rahul_dahiya |
0:fb8047b156bb | 326 | FATFileSystem fs; |
rahul_dahiya |
0:fb8047b156bb | 327 | int err = fs.mount(bd, false); |
rahul_dahiya |
0:fb8047b156bb | 328 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 329 | return err; |
rahul_dahiya |
0:fb8047b156bb | 330 | } |
rahul_dahiya |
0:fb8047b156bb | 331 | |
rahul_dahiya |
0:fb8047b156bb | 332 | // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster) |
rahul_dahiya |
0:fb8047b156bb | 333 | fs.lock(); |
rahul_dahiya |
0:fb8047b156bb | 334 | FRESULT res = f_mkfs(fs._fsid, 1, cluster_size); |
rahul_dahiya |
0:fb8047b156bb | 335 | fs.unlock(); |
rahul_dahiya |
0:fb8047b156bb | 336 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 337 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 338 | } |
rahul_dahiya |
0:fb8047b156bb | 339 | |
rahul_dahiya |
0:fb8047b156bb | 340 | err = fs.unmount(); |
rahul_dahiya |
0:fb8047b156bb | 341 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 342 | return err; |
rahul_dahiya |
0:fb8047b156bb | 343 | } |
rahul_dahiya |
0:fb8047b156bb | 344 | |
rahul_dahiya |
0:fb8047b156bb | 345 | return 0; |
rahul_dahiya |
0:fb8047b156bb | 346 | } |
rahul_dahiya |
0:fb8047b156bb | 347 | |
rahul_dahiya |
0:fb8047b156bb | 348 | int FATFileSystem::reformat(BlockDevice *bd, int allocation_unit) { |
rahul_dahiya |
0:fb8047b156bb | 349 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 350 | if (_id != -1) { |
rahul_dahiya |
0:fb8047b156bb | 351 | if (!bd) { |
rahul_dahiya |
0:fb8047b156bb | 352 | bd = _ffs[_id]; |
rahul_dahiya |
0:fb8047b156bb | 353 | } |
rahul_dahiya |
0:fb8047b156bb | 354 | |
rahul_dahiya |
0:fb8047b156bb | 355 | int err = unmount(); |
rahul_dahiya |
0:fb8047b156bb | 356 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 357 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 358 | return err; |
rahul_dahiya |
0:fb8047b156bb | 359 | } |
rahul_dahiya |
0:fb8047b156bb | 360 | } |
rahul_dahiya |
0:fb8047b156bb | 361 | |
rahul_dahiya |
0:fb8047b156bb | 362 | if (!bd) { |
rahul_dahiya |
0:fb8047b156bb | 363 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 364 | return -ENODEV; |
rahul_dahiya |
0:fb8047b156bb | 365 | } |
rahul_dahiya |
0:fb8047b156bb | 366 | |
rahul_dahiya |
0:fb8047b156bb | 367 | int err = FATFileSystem::format(bd, allocation_unit); |
rahul_dahiya |
0:fb8047b156bb | 368 | if (err) { |
rahul_dahiya |
0:fb8047b156bb | 369 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 370 | return err; |
rahul_dahiya |
0:fb8047b156bb | 371 | } |
rahul_dahiya |
0:fb8047b156bb | 372 | |
rahul_dahiya |
0:fb8047b156bb | 373 | err = mount(bd); |
rahul_dahiya |
0:fb8047b156bb | 374 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 375 | return err; |
rahul_dahiya |
0:fb8047b156bb | 376 | } |
rahul_dahiya |
0:fb8047b156bb | 377 | |
rahul_dahiya |
0:fb8047b156bb | 378 | int FATFileSystem::remove(const char *path) { |
rahul_dahiya |
0:fb8047b156bb | 379 | Deferred<const char*> fpath = fat_path_prefix(_id, path); |
rahul_dahiya |
0:fb8047b156bb | 380 | |
rahul_dahiya |
0:fb8047b156bb | 381 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 382 | FRESULT res = f_unlink(fpath); |
rahul_dahiya |
0:fb8047b156bb | 383 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 384 | |
rahul_dahiya |
0:fb8047b156bb | 385 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 386 | debug_if(FFS_DBG, "f_unlink() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 387 | } |
rahul_dahiya |
0:fb8047b156bb | 388 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 389 | } |
rahul_dahiya |
0:fb8047b156bb | 390 | |
rahul_dahiya |
0:fb8047b156bb | 391 | int FATFileSystem::rename(const char *oldpath, const char *newpath) { |
rahul_dahiya |
0:fb8047b156bb | 392 | Deferred<const char*> oldfpath = fat_path_prefix(_id, oldpath); |
rahul_dahiya |
0:fb8047b156bb | 393 | Deferred<const char*> newfpath = fat_path_prefix(_id, newpath); |
rahul_dahiya |
0:fb8047b156bb | 394 | |
rahul_dahiya |
0:fb8047b156bb | 395 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 396 | FRESULT res = f_rename(oldfpath, newfpath); |
rahul_dahiya |
0:fb8047b156bb | 397 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 398 | |
rahul_dahiya |
0:fb8047b156bb | 399 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 400 | debug_if(FFS_DBG, "f_rename() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 401 | } |
rahul_dahiya |
0:fb8047b156bb | 402 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 403 | } |
rahul_dahiya |
0:fb8047b156bb | 404 | |
rahul_dahiya |
0:fb8047b156bb | 405 | int FATFileSystem::mkdir(const char *path, mode_t mode) { |
rahul_dahiya |
0:fb8047b156bb | 406 | Deferred<const char*> fpath = fat_path_prefix(_id, path); |
rahul_dahiya |
0:fb8047b156bb | 407 | |
rahul_dahiya |
0:fb8047b156bb | 408 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 409 | FRESULT res = f_mkdir(fpath); |
rahul_dahiya |
0:fb8047b156bb | 410 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 411 | |
rahul_dahiya |
0:fb8047b156bb | 412 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 413 | debug_if(FFS_DBG, "f_mkdir() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 414 | } |
rahul_dahiya |
0:fb8047b156bb | 415 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 416 | } |
rahul_dahiya |
0:fb8047b156bb | 417 | |
rahul_dahiya |
0:fb8047b156bb | 418 | int FATFileSystem::stat(const char *path, struct stat *st) { |
rahul_dahiya |
0:fb8047b156bb | 419 | Deferred<const char*> fpath = fat_path_prefix(_id, path); |
rahul_dahiya |
0:fb8047b156bb | 420 | |
rahul_dahiya |
0:fb8047b156bb | 421 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 422 | FILINFO f; |
rahul_dahiya |
0:fb8047b156bb | 423 | memset(&f, 0, sizeof(f)); |
rahul_dahiya |
0:fb8047b156bb | 424 | |
rahul_dahiya |
0:fb8047b156bb | 425 | FRESULT res = f_stat(fpath, &f); |
rahul_dahiya |
0:fb8047b156bb | 426 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 427 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 428 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 429 | } |
rahul_dahiya |
0:fb8047b156bb | 430 | |
rahul_dahiya |
0:fb8047b156bb | 431 | /* ARMCC doesnt support stat(), and these symbols are not defined by the toolchain. */ |
rahul_dahiya |
0:fb8047b156bb | 432 | #ifdef TOOLCHAIN_GCC |
rahul_dahiya |
0:fb8047b156bb | 433 | st->st_size = f.fsize; |
rahul_dahiya |
0:fb8047b156bb | 434 | st->st_mode = 0; |
rahul_dahiya |
0:fb8047b156bb | 435 | st->st_mode |= (f.fattrib & AM_DIR) ? S_IFDIR : S_IFREG; |
rahul_dahiya |
0:fb8047b156bb | 436 | st->st_mode |= (f.fattrib & AM_RDO) ? |
rahul_dahiya |
0:fb8047b156bb | 437 | (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) : |
rahul_dahiya |
0:fb8047b156bb | 438 | (S_IRWXU | S_IRWXG | S_IRWXO); |
rahul_dahiya |
0:fb8047b156bb | 439 | #endif /* TOOLCHAIN_GCC */ |
rahul_dahiya |
0:fb8047b156bb | 440 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 441 | |
rahul_dahiya |
0:fb8047b156bb | 442 | return 0; |
rahul_dahiya |
0:fb8047b156bb | 443 | } |
rahul_dahiya |
0:fb8047b156bb | 444 | |
rahul_dahiya |
0:fb8047b156bb | 445 | void FATFileSystem::lock() { |
rahul_dahiya |
0:fb8047b156bb | 446 | _ffs_mutex->lock(); |
rahul_dahiya |
0:fb8047b156bb | 447 | } |
rahul_dahiya |
0:fb8047b156bb | 448 | |
rahul_dahiya |
0:fb8047b156bb | 449 | void FATFileSystem::unlock() { |
rahul_dahiya |
0:fb8047b156bb | 450 | _ffs_mutex->unlock(); |
rahul_dahiya |
0:fb8047b156bb | 451 | } |
rahul_dahiya |
0:fb8047b156bb | 452 | |
rahul_dahiya |
0:fb8047b156bb | 453 | |
rahul_dahiya |
0:fb8047b156bb | 454 | ////// File operations ////// |
rahul_dahiya |
0:fb8047b156bb | 455 | int FATFileSystem::file_open(fs_file_t *file, const char *path, int flags) { |
rahul_dahiya |
0:fb8047b156bb | 456 | debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", path, getName(), _id); |
rahul_dahiya |
0:fb8047b156bb | 457 | |
rahul_dahiya |
0:fb8047b156bb | 458 | FIL *fh = new FIL; |
rahul_dahiya |
0:fb8047b156bb | 459 | Deferred<const char*> fpath = fat_path_prefix(_id, path); |
rahul_dahiya |
0:fb8047b156bb | 460 | |
rahul_dahiya |
0:fb8047b156bb | 461 | /* POSIX flags -> FatFS open mode */ |
rahul_dahiya |
0:fb8047b156bb | 462 | BYTE openmode; |
rahul_dahiya |
0:fb8047b156bb | 463 | if (flags & O_RDWR) { |
rahul_dahiya |
0:fb8047b156bb | 464 | openmode = FA_READ | FA_WRITE; |
rahul_dahiya |
0:fb8047b156bb | 465 | } else if (flags & O_WRONLY) { |
rahul_dahiya |
0:fb8047b156bb | 466 | openmode = FA_WRITE; |
rahul_dahiya |
0:fb8047b156bb | 467 | } else { |
rahul_dahiya |
0:fb8047b156bb | 468 | openmode = FA_READ; |
rahul_dahiya |
0:fb8047b156bb | 469 | } |
rahul_dahiya |
0:fb8047b156bb | 470 | if (flags & O_CREAT) { |
rahul_dahiya |
0:fb8047b156bb | 471 | if (flags & O_TRUNC) { |
rahul_dahiya |
0:fb8047b156bb | 472 | openmode |= FA_CREATE_ALWAYS; |
rahul_dahiya |
0:fb8047b156bb | 473 | } else { |
rahul_dahiya |
0:fb8047b156bb | 474 | openmode |= FA_OPEN_ALWAYS; |
rahul_dahiya |
0:fb8047b156bb | 475 | } |
rahul_dahiya |
0:fb8047b156bb | 476 | } |
rahul_dahiya |
0:fb8047b156bb | 477 | |
rahul_dahiya |
0:fb8047b156bb | 478 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 479 | FRESULT res = f_open(fh, fpath, openmode); |
rahul_dahiya |
0:fb8047b156bb | 480 | |
rahul_dahiya |
0:fb8047b156bb | 481 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 482 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 483 | debug_if(FFS_DBG, "f_open('w') failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 484 | delete fh; |
rahul_dahiya |
0:fb8047b156bb | 485 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 486 | } |
rahul_dahiya |
0:fb8047b156bb | 487 | |
rahul_dahiya |
0:fb8047b156bb | 488 | if (flags & O_APPEND) { |
rahul_dahiya |
0:fb8047b156bb | 489 | f_lseek(fh, fh->fsize); |
rahul_dahiya |
0:fb8047b156bb | 490 | } |
rahul_dahiya |
0:fb8047b156bb | 491 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 492 | |
rahul_dahiya |
0:fb8047b156bb | 493 | *file = fh; |
rahul_dahiya |
0:fb8047b156bb | 494 | return 0; |
rahul_dahiya |
0:fb8047b156bb | 495 | } |
rahul_dahiya |
0:fb8047b156bb | 496 | |
rahul_dahiya |
0:fb8047b156bb | 497 | int FATFileSystem::file_close(fs_file_t file) { |
rahul_dahiya |
0:fb8047b156bb | 498 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 499 | |
rahul_dahiya |
0:fb8047b156bb | 500 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 501 | FRESULT res = f_close(fh); |
rahul_dahiya |
0:fb8047b156bb | 502 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 503 | |
rahul_dahiya |
0:fb8047b156bb | 504 | delete fh; |
rahul_dahiya |
0:fb8047b156bb | 505 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 506 | } |
rahul_dahiya |
0:fb8047b156bb | 507 | |
rahul_dahiya |
0:fb8047b156bb | 508 | ssize_t FATFileSystem::file_read(fs_file_t file, void *buffer, size_t len) { |
rahul_dahiya |
0:fb8047b156bb | 509 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 510 | |
rahul_dahiya |
0:fb8047b156bb | 511 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 512 | UINT n; |
rahul_dahiya |
0:fb8047b156bb | 513 | FRESULT res = f_read(fh, buffer, len, &n); |
rahul_dahiya |
0:fb8047b156bb | 514 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 515 | |
rahul_dahiya |
0:fb8047b156bb | 516 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 517 | debug_if(FFS_DBG, "f_read() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 518 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 519 | } else { |
rahul_dahiya |
0:fb8047b156bb | 520 | return n; |
rahul_dahiya |
0:fb8047b156bb | 521 | } |
rahul_dahiya |
0:fb8047b156bb | 522 | } |
rahul_dahiya |
0:fb8047b156bb | 523 | |
rahul_dahiya |
0:fb8047b156bb | 524 | ssize_t FATFileSystem::file_write(fs_file_t file, const void *buffer, size_t len) { |
rahul_dahiya |
0:fb8047b156bb | 525 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 526 | |
rahul_dahiya |
0:fb8047b156bb | 527 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 528 | UINT n; |
rahul_dahiya |
0:fb8047b156bb | 529 | FRESULT res = f_write(fh, buffer, len, &n); |
rahul_dahiya |
0:fb8047b156bb | 530 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 531 | |
rahul_dahiya |
0:fb8047b156bb | 532 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 533 | debug_if(FFS_DBG, "f_write() failed: %d", res); |
rahul_dahiya |
0:fb8047b156bb | 534 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 535 | } else { |
rahul_dahiya |
0:fb8047b156bb | 536 | return n; |
rahul_dahiya |
0:fb8047b156bb | 537 | } |
rahul_dahiya |
0:fb8047b156bb | 538 | } |
rahul_dahiya |
0:fb8047b156bb | 539 | |
rahul_dahiya |
0:fb8047b156bb | 540 | int FATFileSystem::file_sync(fs_file_t file) { |
rahul_dahiya |
0:fb8047b156bb | 541 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 542 | |
rahul_dahiya |
0:fb8047b156bb | 543 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 544 | FRESULT res = f_sync(fh); |
rahul_dahiya |
0:fb8047b156bb | 545 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 546 | |
rahul_dahiya |
0:fb8047b156bb | 547 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 548 | debug_if(FFS_DBG, "f_sync() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 549 | } |
rahul_dahiya |
0:fb8047b156bb | 550 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 551 | } |
rahul_dahiya |
0:fb8047b156bb | 552 | |
rahul_dahiya |
0:fb8047b156bb | 553 | off_t FATFileSystem::file_seek(fs_file_t file, off_t offset, int whence) { |
rahul_dahiya |
0:fb8047b156bb | 554 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 555 | |
rahul_dahiya |
0:fb8047b156bb | 556 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 557 | if (whence == SEEK_END) { |
rahul_dahiya |
0:fb8047b156bb | 558 | offset += fh->fsize; |
rahul_dahiya |
0:fb8047b156bb | 559 | } else if(whence==SEEK_CUR) { |
rahul_dahiya |
0:fb8047b156bb | 560 | offset += fh->fptr; |
rahul_dahiya |
0:fb8047b156bb | 561 | } |
rahul_dahiya |
0:fb8047b156bb | 562 | |
rahul_dahiya |
0:fb8047b156bb | 563 | FRESULT res = f_lseek(fh, offset); |
rahul_dahiya |
0:fb8047b156bb | 564 | off_t noffset = fh->fptr; |
rahul_dahiya |
0:fb8047b156bb | 565 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 566 | |
rahul_dahiya |
0:fb8047b156bb | 567 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 568 | debug_if(FFS_DBG, "lseek failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 569 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 570 | } else { |
rahul_dahiya |
0:fb8047b156bb | 571 | return noffset; |
rahul_dahiya |
0:fb8047b156bb | 572 | } |
rahul_dahiya |
0:fb8047b156bb | 573 | } |
rahul_dahiya |
0:fb8047b156bb | 574 | |
rahul_dahiya |
0:fb8047b156bb | 575 | off_t FATFileSystem::file_tell(fs_file_t file) { |
rahul_dahiya |
0:fb8047b156bb | 576 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 577 | |
rahul_dahiya |
0:fb8047b156bb | 578 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 579 | off_t res = fh->fptr; |
rahul_dahiya |
0:fb8047b156bb | 580 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 581 | |
rahul_dahiya |
0:fb8047b156bb | 582 | return res; |
rahul_dahiya |
0:fb8047b156bb | 583 | } |
rahul_dahiya |
0:fb8047b156bb | 584 | |
rahul_dahiya |
0:fb8047b156bb | 585 | off_t FATFileSystem::file_size(fs_file_t file) { |
rahul_dahiya |
0:fb8047b156bb | 586 | FIL *fh = static_cast<FIL*>(file); |
rahul_dahiya |
0:fb8047b156bb | 587 | |
rahul_dahiya |
0:fb8047b156bb | 588 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 589 | off_t res = fh->fsize; |
rahul_dahiya |
0:fb8047b156bb | 590 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 591 | |
rahul_dahiya |
0:fb8047b156bb | 592 | return res; |
rahul_dahiya |
0:fb8047b156bb | 593 | } |
rahul_dahiya |
0:fb8047b156bb | 594 | |
rahul_dahiya |
0:fb8047b156bb | 595 | |
rahul_dahiya |
0:fb8047b156bb | 596 | ////// Dir operations ////// |
rahul_dahiya |
0:fb8047b156bb | 597 | int FATFileSystem::dir_open(fs_dir_t *dir, const char *path) { |
rahul_dahiya |
0:fb8047b156bb | 598 | FATFS_DIR *dh = new FATFS_DIR; |
rahul_dahiya |
0:fb8047b156bb | 599 | Deferred<const char*> fpath = fat_path_prefix(_id, path); |
rahul_dahiya |
0:fb8047b156bb | 600 | |
rahul_dahiya |
0:fb8047b156bb | 601 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 602 | FRESULT res = f_opendir(dh, fpath); |
rahul_dahiya |
0:fb8047b156bb | 603 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 604 | |
rahul_dahiya |
0:fb8047b156bb | 605 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 606 | debug_if(FFS_DBG, "f_opendir() failed: %d\n", res); |
rahul_dahiya |
0:fb8047b156bb | 607 | delete dh; |
rahul_dahiya |
0:fb8047b156bb | 608 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 609 | } |
rahul_dahiya |
0:fb8047b156bb | 610 | |
rahul_dahiya |
0:fb8047b156bb | 611 | *dir = dh; |
rahul_dahiya |
0:fb8047b156bb | 612 | return 0; |
rahul_dahiya |
0:fb8047b156bb | 613 | } |
rahul_dahiya |
0:fb8047b156bb | 614 | |
rahul_dahiya |
0:fb8047b156bb | 615 | int FATFileSystem::dir_close(fs_dir_t dir) { |
rahul_dahiya |
0:fb8047b156bb | 616 | FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); |
rahul_dahiya |
0:fb8047b156bb | 617 | |
rahul_dahiya |
0:fb8047b156bb | 618 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 619 | FRESULT res = f_closedir(dh); |
rahul_dahiya |
0:fb8047b156bb | 620 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 621 | |
rahul_dahiya |
0:fb8047b156bb | 622 | delete dh; |
rahul_dahiya |
0:fb8047b156bb | 623 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 624 | } |
rahul_dahiya |
0:fb8047b156bb | 625 | |
rahul_dahiya |
0:fb8047b156bb | 626 | ssize_t FATFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) { |
rahul_dahiya |
0:fb8047b156bb | 627 | FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); |
rahul_dahiya |
0:fb8047b156bb | 628 | FILINFO finfo; |
rahul_dahiya |
0:fb8047b156bb | 629 | |
rahul_dahiya |
0:fb8047b156bb | 630 | #if _USE_LFN |
rahul_dahiya |
0:fb8047b156bb | 631 | finfo.lfname = ent->d_name; |
rahul_dahiya |
0:fb8047b156bb | 632 | finfo.lfsize = NAME_MAX; |
rahul_dahiya |
0:fb8047b156bb | 633 | #endif // _USE_LFN |
rahul_dahiya |
0:fb8047b156bb | 634 | |
rahul_dahiya |
0:fb8047b156bb | 635 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 636 | FRESULT res = f_readdir(dh, &finfo); |
rahul_dahiya |
0:fb8047b156bb | 637 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 638 | |
rahul_dahiya |
0:fb8047b156bb | 639 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 640 | return fat_error_remap(res); |
rahul_dahiya |
0:fb8047b156bb | 641 | } else if (finfo.fname[0] == 0) { |
rahul_dahiya |
0:fb8047b156bb | 642 | return 0; |
rahul_dahiya |
0:fb8047b156bb | 643 | } |
rahul_dahiya |
0:fb8047b156bb | 644 | |
rahul_dahiya |
0:fb8047b156bb | 645 | ent->d_type = (finfo.fattrib & AM_DIR) ? DT_DIR : DT_REG; |
rahul_dahiya |
0:fb8047b156bb | 646 | |
rahul_dahiya |
0:fb8047b156bb | 647 | #if _USE_LFN |
rahul_dahiya |
0:fb8047b156bb | 648 | if (ent->d_name[0] == 0) { |
rahul_dahiya |
0:fb8047b156bb | 649 | // No long filename so use short filename. |
rahul_dahiya |
0:fb8047b156bb | 650 | strncpy(ent->d_name, finfo.fname, NAME_MAX); |
rahul_dahiya |
0:fb8047b156bb | 651 | } |
rahul_dahiya |
0:fb8047b156bb | 652 | #else |
rahul_dahiya |
0:fb8047b156bb | 653 | strncpy(end->d_name, finfo.fname, len); |
rahul_dahiya |
0:fb8047b156bb | 654 | #endif |
rahul_dahiya |
0:fb8047b156bb | 655 | |
rahul_dahiya |
0:fb8047b156bb | 656 | return 1; |
rahul_dahiya |
0:fb8047b156bb | 657 | } |
rahul_dahiya |
0:fb8047b156bb | 658 | |
rahul_dahiya |
0:fb8047b156bb | 659 | void FATFileSystem::dir_seek(fs_dir_t dir, off_t offset) { |
rahul_dahiya |
0:fb8047b156bb | 660 | FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); |
rahul_dahiya |
0:fb8047b156bb | 661 | |
rahul_dahiya |
0:fb8047b156bb | 662 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 663 | if (offset < dh->index) { |
rahul_dahiya |
0:fb8047b156bb | 664 | f_rewinddir(dh); |
rahul_dahiya |
0:fb8047b156bb | 665 | } |
rahul_dahiya |
0:fb8047b156bb | 666 | while (dh->index < offset) { |
rahul_dahiya |
0:fb8047b156bb | 667 | FILINFO finfo; |
rahul_dahiya |
0:fb8047b156bb | 668 | FRESULT res; |
rahul_dahiya |
0:fb8047b156bb | 669 | #if _USE_LFN |
rahul_dahiya |
0:fb8047b156bb | 670 | char lfname[NAME_MAX]; |
rahul_dahiya |
0:fb8047b156bb | 671 | finfo.lfname = lfname; |
rahul_dahiya |
0:fb8047b156bb | 672 | finfo.lfsize = NAME_MAX; |
rahul_dahiya |
0:fb8047b156bb | 673 | #endif // _USE_LFN |
rahul_dahiya |
0:fb8047b156bb | 674 | res = f_readdir(dh, &finfo); |
rahul_dahiya |
0:fb8047b156bb | 675 | if (res != FR_OK) { |
rahul_dahiya |
0:fb8047b156bb | 676 | break; |
rahul_dahiya |
0:fb8047b156bb | 677 | } else if (finfo.fname[0] == 0) { |
rahul_dahiya |
0:fb8047b156bb | 678 | break; |
rahul_dahiya |
0:fb8047b156bb | 679 | } |
rahul_dahiya |
0:fb8047b156bb | 680 | } |
rahul_dahiya |
0:fb8047b156bb | 681 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 682 | } |
rahul_dahiya |
0:fb8047b156bb | 683 | |
rahul_dahiya |
0:fb8047b156bb | 684 | off_t FATFileSystem::dir_tell(fs_dir_t dir) { |
rahul_dahiya |
0:fb8047b156bb | 685 | FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); |
rahul_dahiya |
0:fb8047b156bb | 686 | |
rahul_dahiya |
0:fb8047b156bb | 687 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 688 | off_t offset = dh->index; |
rahul_dahiya |
0:fb8047b156bb | 689 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 690 | |
rahul_dahiya |
0:fb8047b156bb | 691 | return offset; |
rahul_dahiya |
0:fb8047b156bb | 692 | } |
rahul_dahiya |
0:fb8047b156bb | 693 | |
rahul_dahiya |
0:fb8047b156bb | 694 | void FATFileSystem::dir_rewind(fs_dir_t dir) { |
rahul_dahiya |
0:fb8047b156bb | 695 | FATFS_DIR *dh = static_cast<FATFS_DIR*>(dir); |
rahul_dahiya |
0:fb8047b156bb | 696 | |
rahul_dahiya |
0:fb8047b156bb | 697 | lock(); |
rahul_dahiya |
0:fb8047b156bb | 698 | f_rewinddir(dh); |
rahul_dahiya |
0:fb8047b156bb | 699 | unlock(); |
rahul_dahiya |
0:fb8047b156bb | 700 | } |
rahul_dahiya |
0:fb8047b156bb | 701 |