FLASH File System This file system can mount, read, and enumerate a file system image from Flash memory.

Fork of FlashFileSystem by Adam Green

A filesystem for accessing a read-only file system placed in the internal FLASH memory of the mbed board.
The file system to be mounted by this file system should be created through the use of the fsbld utility on the PC.
This fsbld.zip archive contains the sources for that utility.

As fsbld creates two output files (a binary and a header file), there are two ways to add the resulting file system image:

  1. Concatenate the binary file system to the end of the .bin file created by the mbed online compiler before uploading to the mbed device.
    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 /b Test_LPC1768.bin + FileImage.bin e:\test.bin
  2. Import the header file into your project, include this file in your main file and add 'roFlashDrive' to the FlashfileSystem constructor call.
    eg : static FlashFileSystem flash("flash", roFlashDrive);

A third (optional) parameter in the FlashfileSystem constructor call allows you to specify the size of the FLASH (KB) on the device (default = 512). eg (for a KL25Z device) : static FlashFileSystem flash("flash", NULL, 128);
Note that in this example, the pointer to the header file has been omitted, so we need to append the binary file system ourselves (see above). When you include the binary file system header in your main file, you can also use the roFlashDrive pointer. eg (for a KL25Z device) : static FlashFileSystem flash("flash", roFlashDrive, 128);

NOTE
This file system is case-sensitive.
Calling fopen("/flash/INDEX.html") won't successfully open a file named index.html in the root directory of the flash file system.

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?

UserRevisionLine numberNew 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 }