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.
Fork of F12RFileSystem by
F32RFileSystem.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2017 ARM Limited 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00020 * SOFTWARE. 00021 */ 00022 #include "F32RFileSystem.h" 00023 #include "F32RFileHandle.h" 00024 #include "F32RDirHandle.h" 00025 #include "fsdebug.h" 00026 #include "mbed_debug.h" 00027 00028 F32RFileSystem::F32RFileSystem(StorageInterface* storage_, const char* n) 00029 : FileSystemLike(n), storage(storage_), mounted(false) { 00030 } 00031 00032 F32RFileSystem::~F32RFileSystem() { 00033 } 00034 00035 static bool to_sfn(const char* name, uint8_t* buf) { 00036 memset(buf, '\x20', 8+3); 00037 for(int i = 0; i < 8; i++) { 00038 char c = *name++; 00039 if (c == '\0') { 00040 return true; 00041 } else if (c == '.') { 00042 break; 00043 } else { 00044 buf[i] = toupper(c); 00045 } 00046 } 00047 if (*name == '.') { 00048 name++; 00049 } 00050 for(int i = 8; i < 11; i++) { 00051 char c = *name++; 00052 if (c == '\0') { 00053 break; 00054 } else { 00055 buf[i] = toupper(c); 00056 } 00057 } 00058 return true; 00059 } 00060 00061 FileHandle *F32RFileSystem::open(const char* name, int flags) { 00062 FS_DBG("name=[%s] flags=%d", name, flags); 00063 if (mount() != 0) { 00064 return NULL; 00065 } 00066 00067 #if 1 00068 uint8_t fat[32]; 00069 storage->Read(base_fat, fat, sizeof(fat)); 00070 FS_DBG_HEX(fat, sizeof(fat)); 00071 #endif 00072 00073 uint8_t sfn[8+3]; 00074 to_sfn(name, sfn); 00075 FS_DBG_HEX(sfn, sizeof(sfn)); 00076 cluster_t cluster = root_directory_first_cluster; 00077 int pos = 0; 00078 while(cluster < 0x0ffffff8) { 00079 FS_TEST_ASSERT(cluster >= 2); 00080 uint32_t dir_pos = base_data + (cluster-2)*cluster_size + cluster_head(pos); 00081 uint8_t buf[32]; 00082 storage->Read(dir_pos, buf, sizeof(buf)); 00083 FS_DBG_HEX(buf, sizeof(buf)); 00084 if (buf[0] == 0x00) { 00085 return NULL; 00086 } else if (memcmp(buf, sfn, sizeof(sfn)) == 0) { 00087 return new F32RFileHandle(*this, dir_pos); 00088 } 00089 pos += 32; 00090 if (cluster_head(pos) == 0) { 00091 cluster = fat_read(cluster); 00092 } 00093 } 00094 return NULL; 00095 } 00096 00097 int F32RFileSystem::remove(const char *filename) { 00098 return -1; 00099 } 00100 00101 int F32RFileSystem::rename(const char *oldname, const char *newname) { 00102 return -1; 00103 } 00104 00105 int F32RFileSystem::format() { 00106 return -1; 00107 } 00108 00109 DirHandle *F32RFileSystem::opendir(const char *name) { 00110 FS_DBG("name=[%s]", name); 00111 00112 if (mount() != 0) { 00113 return NULL; 00114 } 00115 return new F32RDirHandle(*this, root_directory_first_cluster); 00116 } 00117 00118 int F32RFileSystem::mkdir(const char *name, mode_t mode) { 00119 return -1; 00120 } 00121 00122 int F32RFileSystem::mount() { 00123 if (storage_peek(0 * 512 + 510, 2) != 0xaa55) { 00124 return -1; 00125 } 00126 uint32_t lba_offset = 0; 00127 struct { // +446 00128 uint8_t flag; // +0 00129 uint8_t first_sector_chs[3]; // +1 00130 uint8_t type; // +4 00131 uint8_t last_sector_chs[3]; // +5 00132 uint32_t sector_start; // +8 00133 uint32_t sector_count; // +12 00134 } partition_entry; 00135 storage->Read(446, (uint8_t*)&partition_entry, sizeof(partition_entry)); 00136 fs_type = partition_entry.type; 00137 FS_DBG_HEX((uint8_t*)&partition_entry, sizeof(partition_entry)); 00138 FS_DBG("fs_type=%02x", fs_type); 00139 if (!is_fat32()) { 00140 debug("fat32 only."); 00141 return -1; 00142 } 00143 if (is_fat12() || is_fat16() || is_fat32()) { 00144 lba_offset = partition_entry.sector_start * 512; 00145 if (storage_peek(lba_offset + 510, 2) != 0xaa55) { 00146 return -1; 00147 } 00148 } 00149 00150 #if 1 00151 FS_DBG("lba_offset=%d", lba_offset); 00152 uint8_t buf[512]; 00153 storage->Read(lba_offset, buf, sizeof(buf)); 00154 FS_DBG_HEX(buf, sizeof(buf)); 00155 #endif 00156 00157 if (storage_peek(lba_offset + 11, 2) != 512) { // verify sector size 00158 return -1; 00159 } 00160 cluster_size = storage_peek(lba_offset + 13, 1) * 512; 00161 sector_t number_of_reserved_sectors = storage_peek(lba_offset + 14, 2); 00162 base_fat = lba_offset + number_of_reserved_sectors * 512; 00163 uint32_t number_of_fats = storage_peek(lba_offset + 16, 1); 00164 FS_TEST_ASSERT(number_of_fats == 1 || number_of_fats == 2); 00165 // fat32 00166 sector_t number_of_per_fat = storage_peek(lba_offset + 0x24, 4); 00167 root_directory_first_cluster = storage_peek(lba_offset + 0x2c, 4); 00168 root_directory_size = fat32_count(root_directory_first_cluster) * cluster_size; 00169 00170 base_data = base_fat + number_of_per_fat * number_of_fats * 512; 00171 00172 FS_DBG("number_of_reserved_sectors=%d", number_of_reserved_sectors); 00173 FS_DBG("number_of_fats=%d", number_of_fats); 00174 00175 FS_DBG("fat32: number_of_per_fat=%d", number_of_per_fat); 00176 FS_DBG("fat32: root_directory_first_cluster=%d", root_directory_first_cluster); 00177 FS_DBG("fat32: root_directory_size=%d", root_directory_size); 00178 00179 FS_DBG("cluster_size=%d", cluster_size); 00180 FS_DBG("base_fat=%d", base_fat); 00181 FS_DBG("base_data=%d", base_data); 00182 00183 mounted = true; 00184 return 0; 00185 } 00186 00187 int F32RFileSystem::unmount() { 00188 mounted = false; 00189 return 0; 00190 } 00191 00192 uint32_t F32RFileSystem::storage_peek(uint32_t offset, int n) { 00193 uint8_t buf[n]; 00194 storage->Read(offset, buf, sizeof(buf)); 00195 uint32_t val = 0; 00196 for(int i = 0; i < n; i++) { 00197 val |= buf[i]<<(i*8); 00198 } 00199 return val; 00200 } 00201 00202 cluster_t F32RFileSystem::fat_read(cluster_t index) { 00203 if (is_fat32()) { 00204 return storage_peek(base_fat + index*4, 4); 00205 } else if (is_fat16()) { 00206 return storage_peek(base_fat + index*2, 2); 00207 } 00208 FS_TEST_ASSERT(is_fat12()); 00209 int i = index / 2 * 3 + (index&1); 00210 cluster_t next = storage_peek(base_fat + i, 2); 00211 if (index & 1) { 00212 next >>= 4; 00213 } else { 00214 next &= 0xfff; 00215 } 00216 return next; 00217 } 00218 00219 int F32RFileSystem::fat32_count(cluster_t cluster) { 00220 int count = 0; 00221 for(; cluster >= 2 && cluster < 0x0ffffff8; count++) { 00222 cluster = fat_read(cluster); 00223 } 00224 return count; 00225 } 00226
Generated on Tue Jul 12 2022 15:15:05 by
1.7.2
