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