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
Committer:
AdamGreen
Date:
Fri Jul 29 01:23:53 2011 +0000
Revision:
0:5ea6e74c35f7
Child:
1:a3cb118c4f6e
Initial version of FLASH File System

Who changed what in which revision?

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