Working version

Dependents:   PUB_RA8875_Bitmap

This version of the FlashFileSystem is directly derived from a library of the same name by Adam Green. See Adam's original at Flash File System.

Important in the use of this library is the generation of the embedded resource. For this there is a companion tool - rofs.exe. Adam provided a link to the source in github. I used that but found I wanted a few more features, so I made a large number of changes.

ROFS.exe Features

  • Bidirectional:
    • Create flash file system from folder of resources
    • Extract resources from flash file system [.h/.bin]
  • w/reduced warnings
  • faster file system building
  • more internal documentation in the generated .h file
  • additional help information added

Windows EXE

  • Contact me by Private Email for a copy - the mbed site is not letting me upload it as a zip.
Committer:
WiredHome
Date:
Thu Apr 30 14:27:05 2020 +0000
Revision:
1:689c997b57bb
Parent:
0:6339b3e34014
Code cleanup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:6339b3e34014 1 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
WiredHome 0:6339b3e34014 2
WiredHome 0:6339b3e34014 3 Licensed under the Apache License, Version 2.0 (the "License");
WiredHome 0:6339b3e34014 4 you may not use this file except in compliance with the License.
WiredHome 0:6339b3e34014 5 You may obtain a copy of the License at
WiredHome 0:6339b3e34014 6
WiredHome 0:6339b3e34014 7 http://www.apache.org/licenses/LICENSE-2.0
WiredHome 0:6339b3e34014 8
WiredHome 0:6339b3e34014 9 Unless required by applicable law or agreed to in writing, software
WiredHome 0:6339b3e34014 10 distributed under the License is distributed on an "AS IS" BASIS,
WiredHome 0:6339b3e34014 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WiredHome 0:6339b3e34014 12 See the License for the specific language governing permissions and
WiredHome 0:6339b3e34014 13 limitations under the License.
WiredHome 0:6339b3e34014 14 */
WiredHome 0:6339b3e34014 15 /* Specifies the classes used to implement the FlashFileSystem which is a
WiredHome 0:6339b3e34014 16 read-only file system that exists in the internal FLASH of the mbed
WiredHome 0:6339b3e34014 17 device.
WiredHome 0:6339b3e34014 18 */
WiredHome 0:6339b3e34014 19 #include <mbed.h>
WiredHome 0:6339b3e34014 20 #include <assert.h>
WiredHome 0:6339b3e34014 21 #include "FlashFileSystem.h"
WiredHome 0:6339b3e34014 22 #include "ffsformat.h"
WiredHome 0:6339b3e34014 23
WiredHome 0:6339b3e34014 24
WiredHome 0:6339b3e34014 25 //#define DEBUG "ROFS"
WiredHome 0:6339b3e34014 26 // ...
WiredHome 0:6339b3e34014 27 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 0:6339b3e34014 28 //
WiredHome 0:6339b3e34014 29 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 1:689c997b57bb 30 #define INFO(x, ...) std::printf("[INF %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 1:689c997b57bb 31 #define WARN(x, ...) std::printf("[WRN %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 1:689c997b57bb 32 #define ERR(x, ...) std::printf("[ERR %s %4d] " x "\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 0:6339b3e34014 33 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 0:6339b3e34014 34 {
WiredHome 0:6339b3e34014 35 int i;
WiredHome 0:6339b3e34014 36 char buf[100] = "0000: ";
WiredHome 0:6339b3e34014 37
WiredHome 0:6339b3e34014 38 if (*title)
WiredHome 0:6339b3e34014 39 INFO("%s", title);
WiredHome 0:6339b3e34014 40 for (i=0; i<count; ) {
WiredHome 0:6339b3e34014 41 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 0:6339b3e34014 42 if ((++i & 0x0F) == 0x00) {
WiredHome 0:6339b3e34014 43 INFO("%s", buf);
WiredHome 0:6339b3e34014 44 if (i < count)
WiredHome 0:6339b3e34014 45 sprintf(buf, "%04X: ", i);
WiredHome 0:6339b3e34014 46 else
WiredHome 0:6339b3e34014 47 buf[0] = '\0';
WiredHome 0:6339b3e34014 48 }
WiredHome 0:6339b3e34014 49 }
WiredHome 0:6339b3e34014 50 if (strlen(buf))
WiredHome 0:6339b3e34014 51 INFO("%s", buf);
WiredHome 0:6339b3e34014 52 }
WiredHome 0:6339b3e34014 53 #else
WiredHome 0:6339b3e34014 54 #define INFO(x, ...)
WiredHome 0:6339b3e34014 55 #define WARN(x, ...)
WiredHome 0:6339b3e34014 56 #define ERR(x, ...)
WiredHome 0:6339b3e34014 57 #define HexDump(a, b, c)
WiredHome 0:6339b3e34014 58 #endif
WiredHome 0:6339b3e34014 59
WiredHome 0:6339b3e34014 60
WiredHome 0:6339b3e34014 61
WiredHome 0:6339b3e34014 62 /* Constructor for FlashFileSystemFileHandle which initializes to the specified
WiredHome 0:6339b3e34014 63 file entry in the image.
WiredHome 0:6339b3e34014 64
WiredHome 0:6339b3e34014 65 Parameters:
WiredHome 0:6339b3e34014 66 pFileStart is the beginning offset of this file in FLASH memory.
WiredHome 0:6339b3e34014 67 pFileEnd is the ending offset (1 bytes past last valid byte) of this file
WiredHome 0:6339b3e34014 68 FLASH memory.
WiredHome 0:6339b3e34014 69 */
WiredHome 0:6339b3e34014 70 FlashFileSystemFileHandle::FlashFileSystemFileHandle(const char* pFileStart,
WiredHome 0:6339b3e34014 71 const char* pFileEnd)
WiredHome 0:6339b3e34014 72 {
WiredHome 0:6339b3e34014 73 m_pFileStart = pFileStart;
WiredHome 0:6339b3e34014 74 m_pFileEnd = pFileEnd;
WiredHome 0:6339b3e34014 75 m_pCurr = pFileStart;
WiredHome 0:6339b3e34014 76 }
WiredHome 0:6339b3e34014 77
WiredHome 0:6339b3e34014 78
WiredHome 0:6339b3e34014 79 // Constructs a blank FlashFileSystemFileHandle object.
WiredHome 0:6339b3e34014 80 FlashFileSystemFileHandle::FlashFileSystemFileHandle()
WiredHome 0:6339b3e34014 81 {
WiredHome 0:6339b3e34014 82 FlashFileSystemFileHandle(NULL, NULL);
WiredHome 0:6339b3e34014 83 }
WiredHome 0:6339b3e34014 84
WiredHome 0:6339b3e34014 85
WiredHome 0:6339b3e34014 86 /* Write the contents of a buffer to the file
WiredHome 0:6339b3e34014 87
WiredHome 0:6339b3e34014 88 Parameters:
WiredHome 0:6339b3e34014 89 pBuffer is the buffer from which to write.
WiredHome 0:6339b3e34014 90 Length is the number of characters to write.
WiredHome 0:6339b3e34014 91
WiredHome 0:6339b3e34014 92 Returns
WiredHome 0:6339b3e34014 93 The number of characters written (possibly 0) on success, -1 on error.
WiredHome 0:6339b3e34014 94 */
WiredHome 0:6339b3e34014 95 ssize_t FlashFileSystemFileHandle::write(const void* pBuffer, size_t Length)
WiredHome 0:6339b3e34014 96 {
WiredHome 0:6339b3e34014 97 // This file system doesn't support writing.
WiredHome 0:6339b3e34014 98 return -1;
WiredHome 0:6339b3e34014 99 }
WiredHome 0:6339b3e34014 100
WiredHome 0:6339b3e34014 101
WiredHome 0:6339b3e34014 102 /* Close the file
WiredHome 0:6339b3e34014 103
WiredHome 0:6339b3e34014 104 Returns
WiredHome 0:6339b3e34014 105 Zero on success, -1 on error.
WiredHome 0:6339b3e34014 106 */
WiredHome 0:6339b3e34014 107 int FlashFileSystemFileHandle::close()
WiredHome 0:6339b3e34014 108 {
WiredHome 0:6339b3e34014 109 m_pFileStart = NULL;
WiredHome 0:6339b3e34014 110 m_pFileEnd = NULL;
WiredHome 0:6339b3e34014 111 m_pCurr = NULL;
WiredHome 0:6339b3e34014 112 INFO("close");
WiredHome 0:6339b3e34014 113 return 0;
WiredHome 0:6339b3e34014 114 }
WiredHome 0:6339b3e34014 115
WiredHome 0:6339b3e34014 116 /* Reads the contents of the file into a buffer.
WiredHome 0:6339b3e34014 117
WiredHome 0:6339b3e34014 118 Parameters
WiredHome 0:6339b3e34014 119 pBuffer is the buffer into which the read should occur.
WiredHome 0:6339b3e34014 120 Length is the number of characters to read into pBuffer.
WiredHome 0:6339b3e34014 121
WiredHome 0:6339b3e34014 122 Returns
WiredHome 0:6339b3e34014 123 The number of characters read (zero at end of file) on success, -1 on error.
WiredHome 0:6339b3e34014 124 */
WiredHome 0:6339b3e34014 125 ssize_t FlashFileSystemFileHandle::read(void* pBuffer, size_t Length)
WiredHome 0:6339b3e34014 126 {
WiredHome 0:6339b3e34014 127 unsigned int BytesLeft;
WiredHome 0:6339b3e34014 128
WiredHome 0:6339b3e34014 129 HexDump("Read", (uint8_t *)pBuffer, Length);
WiredHome 0:6339b3e34014 130 // Don't read more bytes than what are left in the file.
WiredHome 0:6339b3e34014 131 BytesLeft = m_pFileEnd - m_pCurr;
WiredHome 0:6339b3e34014 132 if (Length > BytesLeft) {
WiredHome 0:6339b3e34014 133 Length = BytesLeft;
WiredHome 0:6339b3e34014 134 }
WiredHome 0:6339b3e34014 135 // Copy the bytes from FLASH into the caller provided buffer.
WiredHome 0:6339b3e34014 136 memcpy(pBuffer, m_pCurr, Length);
WiredHome 0:6339b3e34014 137 // Update the file pointer.
WiredHome 0:6339b3e34014 138 m_pCurr += Length;
WiredHome 0:6339b3e34014 139 return Length;
WiredHome 0:6339b3e34014 140 }
WiredHome 0:6339b3e34014 141
WiredHome 0:6339b3e34014 142
WiredHome 0:6339b3e34014 143 /* Check if the handle is for a interactive terminal device .
WiredHome 0:6339b3e34014 144
WiredHome 0:6339b3e34014 145 Parameters
WiredHome 0:6339b3e34014 146 None
WiredHome 0:6339b3e34014 147 Returns
WiredHome 0:6339b3e34014 148 1 if it is a terminal, 0 otherwise
WiredHome 0:6339b3e34014 149 */
WiredHome 0:6339b3e34014 150 int FlashFileSystemFileHandle::isatty()
WiredHome 0:6339b3e34014 151 {
WiredHome 0:6339b3e34014 152 return 0;
WiredHome 0:6339b3e34014 153 }
WiredHome 0:6339b3e34014 154
WiredHome 0:6339b3e34014 155
WiredHome 0:6339b3e34014 156 /* Move the file position to a given offset from a given location.
WiredHome 0:6339b3e34014 157
WiredHome 0:6339b3e34014 158 Parameters
WiredHome 0:6339b3e34014 159 offset is the offset from whence to move to.
WiredHome 0:6339b3e34014 160 whence - SEEK_SET for the start of the file,
WiredHome 0:6339b3e34014 161 SEEK_CUR for the current file position, or
WiredHome 0:6339b3e34014 162 SEEK_END for the end of the file.
WiredHome 0:6339b3e34014 163
WiredHome 0:6339b3e34014 164 Returns
WiredHome 0:6339b3e34014 165 New file position on success, -1 on failure or unsupported
WiredHome 0:6339b3e34014 166 */
WiredHome 0:6339b3e34014 167 off_t FlashFileSystemFileHandle::lseek(off_t offset, int whence)
WiredHome 0:6339b3e34014 168 {
WiredHome 1:689c997b57bb 169 INFO("lseek(%ld, %d)", offset, whence);
WiredHome 0:6339b3e34014 170 switch(whence) {
WiredHome 0:6339b3e34014 171 case SEEK_SET:
WiredHome 0:6339b3e34014 172 m_pCurr = m_pFileStart + offset;
WiredHome 0:6339b3e34014 173 break;
WiredHome 0:6339b3e34014 174 case SEEK_CUR:
WiredHome 0:6339b3e34014 175 m_pCurr += offset;
WiredHome 0:6339b3e34014 176 break;
WiredHome 0:6339b3e34014 177 case SEEK_END:
WiredHome 0:6339b3e34014 178 m_pCurr = (m_pFileEnd - 1) + offset;
WiredHome 0:6339b3e34014 179 break;
WiredHome 0:6339b3e34014 180 default:
WiredHome 0:6339b3e34014 181 INFO("Received unknown origin code (%d) for seek.", whence);
WiredHome 0:6339b3e34014 182 return -1;
WiredHome 0:6339b3e34014 183 }
WiredHome 0:6339b3e34014 184 return (m_pCurr - m_pFileStart);
WiredHome 0:6339b3e34014 185 }
WiredHome 0:6339b3e34014 186
WiredHome 0:6339b3e34014 187
WiredHome 0:6339b3e34014 188 /* Flush any buffers associated with the FileHandle, ensuring it
WiredHome 0:6339b3e34014 189 is up to date on disk. Since the Flash file system is read-only, there
WiredHome 0:6339b3e34014 190 is nothing to do here.
WiredHome 0:6339b3e34014 191
WiredHome 0:6339b3e34014 192 Returns
WiredHome 0:6339b3e34014 193 0 on success or un-needed, -1 on error
WiredHome 0:6339b3e34014 194 */
WiredHome 0:6339b3e34014 195 int FlashFileSystemFileHandle::fsync()
WiredHome 0:6339b3e34014 196 {
WiredHome 0:6339b3e34014 197 return 0;
WiredHome 0:6339b3e34014 198 }
WiredHome 0:6339b3e34014 199
WiredHome 0:6339b3e34014 200
WiredHome 0:6339b3e34014 201 /* Returns the length of the file.
WiredHome 0:6339b3e34014 202
WiredHome 0:6339b3e34014 203 Parameters:
WiredHome 0:6339b3e34014 204 None
WiredHome 0:6339b3e34014 205 Returns:
WiredHome 0:6339b3e34014 206 Length of file.
WiredHome 0:6339b3e34014 207 */
WiredHome 0:6339b3e34014 208 off_t FlashFileSystemFileHandle::flen()
WiredHome 0:6339b3e34014 209 {
WiredHome 0:6339b3e34014 210 return (m_pFileEnd - m_pFileStart);
WiredHome 0:6339b3e34014 211 }
WiredHome 0:6339b3e34014 212
WiredHome 0:6339b3e34014 213
WiredHome 0:6339b3e34014 214
WiredHome 0:6339b3e34014 215 /* Construct and initialize a directory handle enumeration object.
WiredHome 0:6339b3e34014 216
WiredHome 0:6339b3e34014 217 Parameters:
WiredHome 0:6339b3e34014 218 pFLASHBase points to the beginning of the file system in FLASH memory.
WiredHome 0:6339b3e34014 219 pFirstFileEntry is a pointer to the first entry found in this directory.
WiredHome 0:6339b3e34014 220 DirectoryNameLength is the length of the directory name for which this
WiredHome 0:6339b3e34014 221 handle is being used to enumerate.
WiredHome 0:6339b3e34014 222
WiredHome 0:6339b3e34014 223 Returns:
WiredHome 0:6339b3e34014 224 Nothing.
WiredHome 0:6339b3e34014 225 */
WiredHome 0:6339b3e34014 226 FlashFileSystemDirHandle::FlashFileSystemDirHandle(const char* pFLASHBase,
WiredHome 0:6339b3e34014 227 const _SFileSystemEntry* pFirstFileEntry,
WiredHome 0:6339b3e34014 228 unsigned int FileEntriesLeft,
WiredHome 0:6339b3e34014 229 unsigned int DirectoryNameLength)
WiredHome 0:6339b3e34014 230 {
WiredHome 0:6339b3e34014 231 m_pFLASHBase = pFLASHBase;
WiredHome 0:6339b3e34014 232 m_pFirstFileEntry = pFirstFileEntry;
WiredHome 0:6339b3e34014 233 m_pCurrentFileEntry = pFirstFileEntry;
WiredHome 0:6339b3e34014 234 m_FileEntriesLeft = FileEntriesLeft;
WiredHome 0:6339b3e34014 235 m_DirectoryNameLength = DirectoryNameLength;
WiredHome 0:6339b3e34014 236 m_DirectoryEntry.d_name[0] = '\0';
WiredHome 0:6339b3e34014 237 }
WiredHome 0:6339b3e34014 238
WiredHome 0:6339b3e34014 239
WiredHome 0:6339b3e34014 240 // Used to construct a closed directory handle.
WiredHome 0:6339b3e34014 241 FlashFileSystemDirHandle::FlashFileSystemDirHandle()
WiredHome 0:6339b3e34014 242 {
WiredHome 0:6339b3e34014 243 FlashFileSystemDirHandle(NULL, NULL, 0, 0);
WiredHome 0:6339b3e34014 244 }
WiredHome 0:6339b3e34014 245
WiredHome 0:6339b3e34014 246
WiredHome 0:6339b3e34014 247 /* Closes the directory enumeration object.
WiredHome 0:6339b3e34014 248
WiredHome 0:6339b3e34014 249 Parameters:
WiredHome 0:6339b3e34014 250 None.
WiredHome 0:6339b3e34014 251
WiredHome 0:6339b3e34014 252 Returns:
WiredHome 0:6339b3e34014 253 0 on success, or -1 on error.
WiredHome 0:6339b3e34014 254 */
WiredHome 0:6339b3e34014 255 int FlashFileSystemDirHandle::closedir()
WiredHome 0:6339b3e34014 256 {
WiredHome 0:6339b3e34014 257 m_pFLASHBase = NULL;
WiredHome 0:6339b3e34014 258 m_pFirstFileEntry = NULL;
WiredHome 0:6339b3e34014 259 m_pCurrentFileEntry = NULL;
WiredHome 0:6339b3e34014 260 m_FileEntriesLeft = 0;
WiredHome 0:6339b3e34014 261 m_DirectoryNameLength = 0;
WiredHome 0:6339b3e34014 262 m_DirectoryEntry.d_name[0] = '\0';
WiredHome 0:6339b3e34014 263
WiredHome 0:6339b3e34014 264 return 0;
WiredHome 0:6339b3e34014 265 }
WiredHome 0:6339b3e34014 266
WiredHome 0:6339b3e34014 267
WiredHome 0:6339b3e34014 268 /* Return the directory entry at the current position, and
WiredHome 0:6339b3e34014 269 advances the position to the next entry.
WiredHome 0:6339b3e34014 270
WiredHome 0:6339b3e34014 271 Parameters:
WiredHome 0:6339b3e34014 272 None.
WiredHome 0:6339b3e34014 273
WiredHome 0:6339b3e34014 274 Returns:
WiredHome 0:6339b3e34014 275 A pointer to a dirent structure representing the
WiredHome 0:6339b3e34014 276 directory entry at the current position, or NULL on reaching
WiredHome 0:6339b3e34014 277 end of directory or error.
WiredHome 0:6339b3e34014 278 */
WiredHome 0:6339b3e34014 279 struct dirent* FlashFileSystemDirHandle::readdir() {
WiredHome 0:6339b3e34014 280 const char* pPrevEntryName;
WiredHome 0:6339b3e34014 281 const char* pCurrentEntryName;
WiredHome 0:6339b3e34014 282 char* pSlash;
WiredHome 0:6339b3e34014 283 size_t PrefixLength;
WiredHome 0:6339b3e34014 284 unsigned int FileEntriesUsed;
WiredHome 0:6339b3e34014 285 unsigned int FileEntriesLeft;
WiredHome 0:6339b3e34014 286
WiredHome 0:6339b3e34014 287 // Just return now if we have already finished enumerating the entries in
WiredHome 0:6339b3e34014 288 // the directory.
WiredHome 0:6339b3e34014 289 if (!m_pCurrentFileEntry) {
WiredHome 0:6339b3e34014 290 m_DirectoryEntry.d_name[0] = '\0';
WiredHome 0:6339b3e34014 291 return NULL;
WiredHome 0:6339b3e34014 292 }
WiredHome 0:6339b3e34014 293
WiredHome 0:6339b3e34014 294 // Calculate the number of valid entries are left in the file entry array.
WiredHome 0:6339b3e34014 295 FileEntriesUsed = m_pCurrentFileEntry - m_pFirstFileEntry;
WiredHome 0:6339b3e34014 296 FileEntriesLeft = m_FileEntriesLeft - FileEntriesUsed;
WiredHome 0:6339b3e34014 297
WiredHome 0:6339b3e34014 298 // Fill in the directory entry structure for the current entry.
WiredHome 0:6339b3e34014 299 pPrevEntryName = m_pFLASHBase +
WiredHome 0:6339b3e34014 300 m_pCurrentFileEntry->FilenameOffset;
WiredHome 0:6339b3e34014 301 strncpy(m_DirectoryEntry.d_name,
WiredHome 0:6339b3e34014 302 pPrevEntryName + m_DirectoryNameLength,
WiredHome 0:6339b3e34014 303 sizeof(m_DirectoryEntry.d_name));
WiredHome 0:6339b3e34014 304 m_DirectoryEntry.d_name[sizeof(m_DirectoryEntry.d_name) - 1] = '\0';
WiredHome 0:6339b3e34014 305
WiredHome 0:6339b3e34014 306 // If the entry to be returned contains a slash then this is a directory
WiredHome 0:6339b3e34014 307 // entry.
WiredHome 0:6339b3e34014 308 pSlash = strchr(m_DirectoryEntry.d_name, '/');
WiredHome 0:6339b3e34014 309 if (pSlash) {
WiredHome 0:6339b3e34014 310 // I am truncating everything after the slash but leaving the
WiredHome 0:6339b3e34014 311 // slash so that I can tell it is a directory and not a file.
WiredHome 0:6339b3e34014 312 pSlash[1] = '\0';
WiredHome 0:6339b3e34014 313 }
WiredHome 0:6339b3e34014 314
WiredHome 0:6339b3e34014 315 // Skip entries that have the same prefix as the current entry. This
WiredHome 0:6339b3e34014 316 // will skip the files in the same sub-tree.
WiredHome 0:6339b3e34014 317 PrefixLength = strlen(m_DirectoryEntry.d_name) + m_DirectoryNameLength;
WiredHome 0:6339b3e34014 318 do {
WiredHome 0:6339b3e34014 319 m_pCurrentFileEntry++;
WiredHome 0:6339b3e34014 320 FileEntriesLeft--;
WiredHome 0:6339b3e34014 321 pCurrentEntryName = m_pFLASHBase + m_pCurrentFileEntry->FilenameOffset;
WiredHome 0:6339b3e34014 322 } while (FileEntriesLeft &&
WiredHome 0:6339b3e34014 323 0 == strncmp(pPrevEntryName, pCurrentEntryName, PrefixLength));
WiredHome 0:6339b3e34014 324
WiredHome 0:6339b3e34014 325 // If we have walked past the end of all file entries in the file system or
WiredHome 0:6339b3e34014 326 // the prefix no longer matches this directory, then there are no more files
WiredHome 0:6339b3e34014 327 // for this directory enumeration.
WiredHome 0:6339b3e34014 328 if (0 == FileEntriesLeft ||
WiredHome 0:6339b3e34014 329 0 != strncmp(pPrevEntryName, pCurrentEntryName, m_DirectoryNameLength)) {
WiredHome 0:6339b3e34014 330 m_pCurrentFileEntry = NULL;
WiredHome 0:6339b3e34014 331 }
WiredHome 0:6339b3e34014 332
WiredHome 0:6339b3e34014 333 // Return a pointer to the directory entry structure that was previously
WiredHome 0:6339b3e34014 334 // setup.
WiredHome 0:6339b3e34014 335 return &m_DirectoryEntry;
WiredHome 0:6339b3e34014 336 }
WiredHome 0:6339b3e34014 337
WiredHome 0:6339b3e34014 338
WiredHome 0:6339b3e34014 339 //Resets the position to the beginning of the directory.
WiredHome 0:6339b3e34014 340 void FlashFileSystemDirHandle::rewinddir()
WiredHome 0:6339b3e34014 341 {
WiredHome 0:6339b3e34014 342 m_pCurrentFileEntry = m_pFirstFileEntry;
WiredHome 0:6339b3e34014 343 }
WiredHome 0:6339b3e34014 344
WiredHome 0:6339b3e34014 345
WiredHome 0:6339b3e34014 346 /* Returns the current position of the DirHandle.
WiredHome 0:6339b3e34014 347
WiredHome 0:6339b3e34014 348 Parameters:
WiredHome 0:6339b3e34014 349 None.
WiredHome 0:6339b3e34014 350
WiredHome 0:6339b3e34014 351 Returns:
WiredHome 0:6339b3e34014 352 The current position, or -1 on error.
WiredHome 0:6339b3e34014 353 */
WiredHome 0:6339b3e34014 354 off_t FlashFileSystemDirHandle::telldir()
WiredHome 0:6339b3e34014 355 {
WiredHome 0:6339b3e34014 356 return (off_t)m_pCurrentFileEntry;
WiredHome 0:6339b3e34014 357 }
WiredHome 0:6339b3e34014 358
WiredHome 0:6339b3e34014 359
WiredHome 0:6339b3e34014 360 /* Sets the position of the DirHandle.
WiredHome 0:6339b3e34014 361
WiredHome 0:6339b3e34014 362 Parameters:
WiredHome 0:6339b3e34014 363 Location is the location to seek to. Must be a value returned
WiredHome 0:6339b3e34014 364 by telldir.
WiredHome 0:6339b3e34014 365
WiredHome 0:6339b3e34014 366 Returns;
WiredHome 0:6339b3e34014 367 Nothing.
WiredHome 0:6339b3e34014 368 */
WiredHome 0:6339b3e34014 369 void FlashFileSystemDirHandle::seekdir(off_t Location)
WiredHome 0:6339b3e34014 370 {
WiredHome 0:6339b3e34014 371 SFileSystemEntry* pLocation = (SFileSystemEntry*)Location;
WiredHome 0:6339b3e34014 372
WiredHome 0:6339b3e34014 373 assert ( NULL != pLocation &&
WiredHome 0:6339b3e34014 374 pLocation > m_pFirstFileEntry &&
WiredHome 1:689c997b57bb 375 (unsigned int)(pLocation - m_pFirstFileEntry) < m_FileEntriesLeft );
WiredHome 0:6339b3e34014 376 m_pCurrentFileEntry = pLocation;
WiredHome 0:6339b3e34014 377 }
WiredHome 0:6339b3e34014 378
WiredHome 0:6339b3e34014 379
WiredHome 0:6339b3e34014 380
WiredHome 0:6339b3e34014 381 // Structure used to hold context about current filename search.
WiredHome 0:6339b3e34014 382 struct SSearchContext {
WiredHome 0:6339b3e34014 383 // Name of file to be found in file system image.
WiredHome 0:6339b3e34014 384 const char* pKey;
WiredHome 0:6339b3e34014 385 // Base pointer for the file system image.
WiredHome 0:6339b3e34014 386 const char* pFLASHBase;
WiredHome 0:6339b3e34014 387 };
WiredHome 0:6339b3e34014 388
WiredHome 0:6339b3e34014 389
WiredHome 0:6339b3e34014 390 /* Internal routine used as callback for bsearch() when searching for a
WiredHome 0:6339b3e34014 391 requested filename in the FLASH file system image.
WiredHome 0:6339b3e34014 392
WiredHome 0:6339b3e34014 393 pvKey is a pointer to the SSearchContext object for this search.
WiredHome 0:6339b3e34014 394 pvEntry is a pointer to the current file system entry being checked by
WiredHome 0:6339b3e34014 395 bsearch().
WiredHome 0:6339b3e34014 396
WiredHome 0:6339b3e34014 397 Returns <0 if filename to find is lower in sort order than current entry.
WiredHome 0:6339b3e34014 398 0 if filename to find is the same as the current entry.
WiredHome 0:6339b3e34014 399 >0 if filename to find is higher in sort order than current entry.
WiredHome 0:6339b3e34014 400 */
WiredHome 0:6339b3e34014 401 static int _CompareKeyToFileEntry(const void* pvKey, const void* pvEntry)
WiredHome 0:6339b3e34014 402 {
WiredHome 0:6339b3e34014 403 const SSearchContext* pContext = (const SSearchContext*)pvKey;
WiredHome 0:6339b3e34014 404 const char* pKey = pContext->pKey;
WiredHome 0:6339b3e34014 405 const SFileSystemEntry* pEntry = (const SFileSystemEntry*)pvEntry;
WiredHome 0:6339b3e34014 406 const char* pEntryName = pContext->pFLASHBase + pEntry->FilenameOffset;
WiredHome 0:6339b3e34014 407
WiredHome 0:6339b3e34014 408 return strcmp(pKey, pEntryName);
WiredHome 0:6339b3e34014 409 }
WiredHome 0:6339b3e34014 410
WiredHome 0:6339b3e34014 411
WiredHome 0:6339b3e34014 412 /* Constructor for FlashFileSystem
WiredHome 0:6339b3e34014 413
WiredHome 0:6339b3e34014 414 Parameters:
WiredHome 0:6339b3e34014 415 pName is the root name to be used for this file system in fopen()
WiredHome 0:6339b3e34014 416 pathnames.
WiredHome 0:6339b3e34014 417 pFlashDrive (optional) is a pointer to the read-only file system (const char array).
WiredHome 0:6339b3e34014 418 When pFlashDrive is not specified, it is up to the user to append the
WiredHome 0:6339b3e34014 419 read-only file system file to the compiled binary.
WiredHome 0:6339b3e34014 420 FlashSize (optional) is the size of the FLASH (KB) on the device to
WiredHome 0:6339b3e34014 421 search through for the file system signature (default = 512).
WiredHome 0:6339b3e34014 422 */
WiredHome 0:6339b3e34014 423 FlashFileSystem::FlashFileSystem(const char* pName, const uint8_t *pFlashDrive, const uint32_t FlashSize) : FileSystemLike(pName)
WiredHome 0:6339b3e34014 424 {
WiredHome 0:6339b3e34014 425 static const char FileSystemSignature[] = FILE_SYSTEM_SIGNATURE;
WiredHome 0:6339b3e34014 426 SFileSystemHeader* pHeader = NULL;
WiredHome 0:6339b3e34014 427 char* pCurr = (char*)(FlashSize * 1024) - sizeof(pHeader->FileSystemSignature);
WiredHome 0:6339b3e34014 428
WiredHome 0:6339b3e34014 429 // Initialize the members
WiredHome 0:6339b3e34014 430 m_pFLASHBase = NULL;
WiredHome 0:6339b3e34014 431 m_FileCount = 0;
WiredHome 0:6339b3e34014 432 m_pFileEntries = NULL;
WiredHome 0:6339b3e34014 433
WiredHome 0:6339b3e34014 434 INFO("constructor.");
WiredHome 0:6339b3e34014 435 wait_ms(200);
WiredHome 0:6339b3e34014 436 // Scan backwards through 512k FLASH looking for the file system signature
WiredHome 0:6339b3e34014 437 // NOTE: The file system image should be located after this code itself
WiredHome 0:6339b3e34014 438 // so stop the search.
WiredHome 0:6339b3e34014 439 if (pFlashDrive == NULL) {
WiredHome 0:6339b3e34014 440 while (pCurr > FileSystemSignature) {
WiredHome 0:6339b3e34014 441 if (0 == memcmp(pCurr, FileSystemSignature, sizeof(pHeader->FileSystemSignature))) {
WiredHome 0:6339b3e34014 442 break;
WiredHome 0:6339b3e34014 443 }
WiredHome 0:6339b3e34014 444 pCurr--;
WiredHome 0:6339b3e34014 445 }
WiredHome 0:6339b3e34014 446 if (pCurr <= FileSystemSignature) {
WiredHome 0:6339b3e34014 447 INFO("Failed to find file system image in ROM.");
WiredHome 0:6339b3e34014 448 return;
WiredHome 0:6339b3e34014 449 } else {
WiredHome 0:6339b3e34014 450 INFO("found it at %p", pCurr);
WiredHome 0:6339b3e34014 451 }
WiredHome 0:6339b3e34014 452 } else {
WiredHome 0:6339b3e34014 453 pCurr = (char *)pFlashDrive;
WiredHome 0:6339b3e34014 454 }
WiredHome 0:6339b3e34014 455 if (((unsigned int)pCurr & 0x3) != 0) {
WiredHome 1:689c997b57bb 456 INFO("File system image at address %p isn't 4-byte aligned.", pCurr);
WiredHome 0:6339b3e34014 457 return;
WiredHome 0:6339b3e34014 458 }
WiredHome 0:6339b3e34014 459
WiredHome 0:6339b3e34014 460 // Record the location of the file system image in the member fields.
WiredHome 0:6339b3e34014 461 m_pFLASHBase = pCurr;
WiredHome 0:6339b3e34014 462 pHeader = (SFileSystemHeader*)m_pFLASHBase;
WiredHome 0:6339b3e34014 463 m_FileCount = pHeader->FileCount;
WiredHome 0:6339b3e34014 464 m_pFileEntries = (SFileSystemEntry*)(m_pFLASHBase + sizeof(*pHeader));
WiredHome 0:6339b3e34014 465 INFO(" end constructor.");
WiredHome 0:6339b3e34014 466 }
WiredHome 0:6339b3e34014 467
WiredHome 0:6339b3e34014 468
WiredHome 0:6339b3e34014 469 /* Opens specified file in FLASH file system when an appropriate call to
WiredHome 0:6339b3e34014 470 fopen() is made.
WiredHome 0:6339b3e34014 471
WiredHome 0:6339b3e34014 472 pFilename is the name of the file to be opened within the file system.
WiredHome 0:6339b3e34014 473 Flags specify flags to determine open mode of file. This file system only
WiredHome 0:6339b3e34014 474 support O_RDONLY.
WiredHome 0:6339b3e34014 475
WiredHome 0:6339b3e34014 476 Returns NULL if an error was encountered or a pointer to a FileHandle object
WiredHome 0:6339b3e34014 477 representing the requrested file otherwise.
WiredHome 0:6339b3e34014 478 */
WiredHome 0:6339b3e34014 479 FileHandle* FlashFileSystem::open(const char* pFilename, int Flags)
WiredHome 0:6339b3e34014 480 {
WiredHome 0:6339b3e34014 481 const SFileSystemEntry* pEntry = NULL;
WiredHome 0:6339b3e34014 482 FlashFileSystemFileHandle* pFileHandle = NULL;
WiredHome 0:6339b3e34014 483 SSearchContext SearchContext;
WiredHome 0:6339b3e34014 484
WiredHome 0:6339b3e34014 485 INFO("Attempt to open file /FLASH/%s with flags:%x", pFilename, Flags);
WiredHome 0:6339b3e34014 486
WiredHome 0:6339b3e34014 487 // Can't find the file if file system hasn't been mounted.
WiredHome 0:6339b3e34014 488 if (!IsMounted()) {
WiredHome 0:6339b3e34014 489 INFO("not mounted.");
WiredHome 0:6339b3e34014 490 return NULL;
WiredHome 0:6339b3e34014 491 }
WiredHome 0:6339b3e34014 492
WiredHome 0:6339b3e34014 493 // Can only open files in FLASH for read.
WiredHome 0:6339b3e34014 494 if (O_RDONLY != Flags) {
WiredHome 0:6339b3e34014 495 INFO("Can only open files for reading.");
WiredHome 0:6339b3e34014 496 }
WiredHome 0:6339b3e34014 497
WiredHome 0:6339b3e34014 498 // Attempt to find the specified file in the file system image.
WiredHome 0:6339b3e34014 499 SearchContext.pKey = pFilename;
WiredHome 0:6339b3e34014 500 SearchContext.pFLASHBase = m_pFLASHBase;
WiredHome 0:6339b3e34014 501 pEntry = (const SFileSystemEntry*) bsearch(&SearchContext,
WiredHome 0:6339b3e34014 502 m_pFileEntries,
WiredHome 0:6339b3e34014 503 m_FileCount,
WiredHome 0:6339b3e34014 504 sizeof(*m_pFileEntries),
WiredHome 0:6339b3e34014 505 _CompareKeyToFileEntry);
WiredHome 0:6339b3e34014 506 if(!pEntry) {
WiredHome 0:6339b3e34014 507 // Create failure response.
WiredHome 0:6339b3e34014 508 INFO("Failed to find '%s' in file system image.", pFilename);
WiredHome 0:6339b3e34014 509 return NULL;
WiredHome 0:6339b3e34014 510 }
WiredHome 0:6339b3e34014 511
WiredHome 0:6339b3e34014 512 // Attempt to find a free file handle.
WiredHome 0:6339b3e34014 513 pFileHandle = FindFreeFileHandle();
WiredHome 0:6339b3e34014 514 if (!pFileHandle) {
WiredHome 0:6339b3e34014 515 INFO("File handle table is full.");
WiredHome 0:6339b3e34014 516 return NULL;
WiredHome 0:6339b3e34014 517 }
WiredHome 0:6339b3e34014 518
WiredHome 0:6339b3e34014 519 // Initialize the file handle and return it to caller.
WiredHome 0:6339b3e34014 520 pFileHandle->SetEntry(m_pFLASHBase + pEntry->FileBinaryOffset,
WiredHome 0:6339b3e34014 521 m_pFLASHBase + pEntry->FileBinaryOffset + pEntry->FileBinarySize);
WiredHome 0:6339b3e34014 522 INFO("file opened ok.");
WiredHome 0:6339b3e34014 523 return pFileHandle;
WiredHome 0:6339b3e34014 524 }
WiredHome 0:6339b3e34014 525
WiredHome 0:6339b3e34014 526 DirHandle* FlashFileSystem::opendir(const char *pDirectoryName)
WiredHome 0:6339b3e34014 527 {
WiredHome 0:6339b3e34014 528 const SFileSystemEntry* pEntry = m_pFileEntries;
WiredHome 0:6339b3e34014 529 unsigned int DirectoryNameLength;
WiredHome 0:6339b3e34014 530 unsigned int i;
WiredHome 0:6339b3e34014 531
WiredHome 0:6339b3e34014 532 assert ( pDirectoryName);
WiredHome 0:6339b3e34014 533
WiredHome 0:6339b3e34014 534 // Removing leading slash since the file system image doesn't contain
WiredHome 0:6339b3e34014 535 // leading slashes.
WiredHome 0:6339b3e34014 536 if ('/' == pDirectoryName[0]) {
WiredHome 0:6339b3e34014 537 pDirectoryName++;
WiredHome 0:6339b3e34014 538 }
WiredHome 0:6339b3e34014 539
WiredHome 0:6339b3e34014 540 // Make sure that the directory name length would include the trailing
WiredHome 0:6339b3e34014 541 // slash.
WiredHome 0:6339b3e34014 542 DirectoryNameLength = strlen(pDirectoryName);
WiredHome 0:6339b3e34014 543 if (0 != DirectoryNameLength && '/' != pDirectoryName[DirectoryNameLength-1]) {
WiredHome 0:6339b3e34014 544 // Add the implicit slash to this count.
WiredHome 0:6339b3e34014 545 DirectoryNameLength++;
WiredHome 0:6339b3e34014 546 }
WiredHome 0:6339b3e34014 547
WiredHome 0:6339b3e34014 548 // Search through the file entries from the beginning to find the first
WiredHome 0:6339b3e34014 549 // entry which has pDirectoryName/ as the prefix.
WiredHome 0:6339b3e34014 550 for (i = 0 ; i < m_FileCount ; i++) {
WiredHome 0:6339b3e34014 551 const char* pEntryFilename = pEntry->FilenameOffset + m_pFLASHBase;
WiredHome 0:6339b3e34014 552
WiredHome 0:6339b3e34014 553 if (0 == DirectoryNameLength ||
WiredHome 0:6339b3e34014 554 (pEntryFilename == strstr(pEntryFilename, pDirectoryName) &&
WiredHome 0:6339b3e34014 555 '/' == pEntryFilename[DirectoryNameLength-1]) ) {
WiredHome 0:6339b3e34014 556 // Found the beginning of the list of files/folders for the
WiredHome 0:6339b3e34014 557 // requested directory so return it to the caller.
WiredHome 0:6339b3e34014 558 FlashFileSystemDirHandle* pDirHandle = FindFreeDirHandle();
WiredHome 0:6339b3e34014 559 if (!pDirHandle) {
WiredHome 0:6339b3e34014 560 INFO("Dir handle table is full.");
WiredHome 0:6339b3e34014 561 return NULL;
WiredHome 0:6339b3e34014 562 }
WiredHome 0:6339b3e34014 563 pDirHandle->SetEntry(m_pFLASHBase,
WiredHome 0:6339b3e34014 564 pEntry,
WiredHome 0:6339b3e34014 565 m_FileCount - (pEntry - m_pFileEntries),
WiredHome 0:6339b3e34014 566 DirectoryNameLength);
WiredHome 0:6339b3e34014 567 return pDirHandle;
WiredHome 0:6339b3e34014 568 }
WiredHome 0:6339b3e34014 569 // Advance to the next file entry
WiredHome 0:6339b3e34014 570 pEntry++;
WiredHome 0:6339b3e34014 571 }
WiredHome 0:6339b3e34014 572 // Get here when the requested directory wasn't found.
WiredHome 0:6339b3e34014 573 WARN("Failed to find '%s' directory in file system image.",
WiredHome 0:6339b3e34014 574 pDirectoryName);
WiredHome 0:6339b3e34014 575 return NULL;
WiredHome 0:6339b3e34014 576 }
WiredHome 0:6339b3e34014 577
WiredHome 0:6339b3e34014 578
WiredHome 0:6339b3e34014 579 /* Protected method which attempts to find a free file handle in the object's
WiredHome 0:6339b3e34014 580 file handle table.
WiredHome 0:6339b3e34014 581
WiredHome 0:6339b3e34014 582 Parameters:
WiredHome 0:6339b3e34014 583 None
WiredHome 0:6339b3e34014 584
WiredHome 0:6339b3e34014 585 Returns:
WiredHome 0:6339b3e34014 586 Pointer to first free file handle entry or NULL if the table is full.
WiredHome 0:6339b3e34014 587 */
WiredHome 0:6339b3e34014 588 FlashFileSystemFileHandle* FlashFileSystem::FindFreeFileHandle()
WiredHome 0:6339b3e34014 589 {
WiredHome 0:6339b3e34014 590 size_t i;
WiredHome 0:6339b3e34014 591
WiredHome 0:6339b3e34014 592 // Iterate through the file handle array, looking for a close file handle.
WiredHome 0:6339b3e34014 593 for (i = 0 ; i < sizeof(m_FileHandles)/sizeof(m_FileHandles[0]) ; i++) {
WiredHome 0:6339b3e34014 594 if (m_FileHandles[i].IsClosed()) {
WiredHome 0:6339b3e34014 595 return &(m_FileHandles[i]);
WiredHome 0:6339b3e34014 596 }
WiredHome 0:6339b3e34014 597 }
WiredHome 0:6339b3e34014 598 // If we get here, then no free entries were found.
WiredHome 0:6339b3e34014 599 WARN("no free entries found");
WiredHome 0:6339b3e34014 600 return NULL;
WiredHome 0:6339b3e34014 601 }
WiredHome 0:6339b3e34014 602
WiredHome 0:6339b3e34014 603
WiredHome 0:6339b3e34014 604 /* Protected method which attempts to find a free dir handle in the object's
WiredHome 0:6339b3e34014 605 directory handle table.
WiredHome 0:6339b3e34014 606
WiredHome 0:6339b3e34014 607 Parameters:
WiredHome 0:6339b3e34014 608 None
WiredHome 0:6339b3e34014 609
WiredHome 0:6339b3e34014 610 Returns:
WiredHome 0:6339b3e34014 611 Pointer to first free directory handle entry or NULL if the table is full.
WiredHome 0:6339b3e34014 612 */
WiredHome 0:6339b3e34014 613 FlashFileSystemDirHandle* FlashFileSystem::FindFreeDirHandle()
WiredHome 0:6339b3e34014 614 {
WiredHome 0:6339b3e34014 615 size_t i;
WiredHome 0:6339b3e34014 616
WiredHome 0:6339b3e34014 617 // Iterate through the direcotry handle array, looking for a closed
WiredHome 0:6339b3e34014 618 // directory handle.
WiredHome 0:6339b3e34014 619 for (i = 0 ; i < sizeof(m_DirHandles)/sizeof(m_DirHandles[0]) ; i++) {
WiredHome 0:6339b3e34014 620 if (m_DirHandles[i].IsClosed()) {
WiredHome 0:6339b3e34014 621 return &(m_DirHandles[i]);
WiredHome 0:6339b3e34014 622 }
WiredHome 0:6339b3e34014 623 }
WiredHome 0:6339b3e34014 624 // If we get here, then no free entries were found.
WiredHome 0:6339b3e34014 625 WARN("no free entries found");
WiredHome 0:6339b3e34014 626 return NULL;
WiredHome 0:6339b3e34014 627 }