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.
FlashFileSystem.h
00001 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/) 00002 00003 Licensed under the Apache License, Version 2.0 (the "License"); 00004 you may not use this file except in compliance with the License. 00005 You may obtain a copy of the License at 00006 00007 http://www.apache.org/licenses/LICENSE-2.0 00008 00009 Unless required by applicable law or agreed to in writing, software 00010 distributed under the License is distributed on an "AS IS" BASIS, 00011 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 See the License for the specific language governing permissions and 00013 limitations under the License. 00014 */ 00015 /* Specifies the classes used to implement the FlashFileSystem which is a 00016 read-only file system that exists in the internal FLASH of the mbed 00017 device. 00018 */ 00019 #ifndef _FLASHFILESYSTEM_H_ 00020 #define _FLASHFILESYSTEM_H_ 00021 00022 #include "FileSystemLike.h" 00023 00024 00025 // Forward declare file system entry structure used internally in 00026 // FlashFileSystem. 00027 struct _SFileSystemEntry; 00028 00029 00030 00031 // Represents an opened file object in the FlashFileSystem. 00032 class FlashFileSystemFileHandle : public FileHandle 00033 { 00034 public: 00035 FlashFileSystemFileHandle(); 00036 FlashFileSystemFileHandle(const char* pFileStart, const char* pFileEnd); 00037 00038 // FileHandle interface methods. 00039 virtual ssize_t write(const void* buffer, size_t length); 00040 virtual int close(); 00041 virtual ssize_t read(void* buffer, size_t length); 00042 virtual int isatty(); 00043 virtual off_t lseek(off_t offset, int whence); 00044 virtual int fsync(); 00045 virtual off_t flen(); 00046 00047 // Used by FlashFileSystem to maintain entries in its handle table. 00048 void SetEntry(const char* pFileStart, const char* pFileEnd) 00049 { 00050 m_pFileStart = pFileStart; 00051 m_pFileEnd = pFileEnd; 00052 m_pCurr = pFileStart; 00053 } 00054 int IsClosed() 00055 { 00056 return (NULL == m_pFileStart); 00057 } 00058 00059 protected: 00060 // Beginning offset of file in FLASH memory. 00061 const char* m_pFileStart; 00062 // Ending offset of file in FLASH memory. 00063 const char* m_pFileEnd; 00064 // Current position in file to be updated by read and seek operations. 00065 const char* m_pCurr; 00066 }; 00067 00068 00069 // Represents an open directory in the FlashFileSystem. 00070 class FlashFileSystemDirHandle : public DirHandle 00071 { 00072 public: 00073 // Constructors 00074 FlashFileSystemDirHandle(); 00075 FlashFileSystemDirHandle(const char* pFLASHBase, 00076 const _SFileSystemEntry* pFirstFileEntry, 00077 unsigned int FileEntriesLeft, 00078 unsigned int DirectoryNameLength); 00079 00080 // Used by FlashFileSystem to maintain DirHandle entries in its cache. 00081 void SetEntry(const char* pFLASHBase, 00082 const _SFileSystemEntry* pFirstFileEntry, 00083 unsigned int FileEntriesLeft, 00084 unsigned int DirectoryNameLength) 00085 { 00086 m_pFLASHBase = pFLASHBase; 00087 m_pFirstFileEntry = pFirstFileEntry; 00088 m_pCurrentFileEntry = pFirstFileEntry; 00089 m_FileEntriesLeft = FileEntriesLeft; 00090 m_DirectoryNameLength = DirectoryNameLength; 00091 } 00092 int IsClosed() 00093 { 00094 return (NULL == m_pFirstFileEntry); 00095 } 00096 00097 // Methods defined by DirHandle interface. 00098 virtual int closedir(); 00099 virtual struct dirent *readdir(); 00100 virtual void rewinddir(); 00101 virtual off_t telldir(); 00102 virtual void seekdir(off_t location); 00103 00104 protected: 00105 // The first file entry for this directory. rewinddir() takes the 00106 // iterator back to here. 00107 const _SFileSystemEntry* m_pFirstFileEntry; 00108 // The next file entry to be returned for this directory enumeration. 00109 const _SFileSystemEntry* m_pCurrentFileEntry; 00110 // Pointer to where the file system image is located in the device's FLASH. 00111 const char* m_pFLASHBase; 00112 // Contents of previously return directory entry structure. 00113 struct dirent m_DirectoryEntry; 00114 // This is the length of the directory name which was opened. When the 00115 // first m_DirectoryNameLength characters change then we have iterated 00116 // through to a different directory. 00117 unsigned int m_DirectoryNameLength; 00118 // The number of entries left in the file system file entries array. 00119 unsigned int m_FileEntriesLeft; 00120 }; 00121 00122 00123 00124 /** A filesystem for accessing a read-only file system placed in the internal\n 00125 * FLASH memory of the mbed board. 00126 *\n 00127 * The file system to be mounted by this file system should be created through\n 00128 * the use of the fsbld utility on the PC.\n 00129 *\n 00130 * As fsbld creates two output files (a binary and a header file), there are two\n 00131 * ways to add the resulting file system image:\n 00132 * -# Concatenate the binary file system to the end of the .bin file created\n 00133 * by the mbed online compiler before uploading to the mbed device.\n 00134 * -# Import the header file into your project, include this file in your main\n 00135 * file and add 'roFlashDrive' to the FlashfileSystem constructor call.\n 00136 * eg : static FlashFileSystem flash("flash", roFlashDrive);\n 00137 * 00138 * A third (optional) parameter in the FlashfileSystem constructor call allows\n 00139 * you to specify the size of the FLASH (KB) on the device (default = 512).\n 00140 * eg (for a KL25Z device) : static FlashFileSystem flash("flash", NULL, 128);\n 00141 * Note that in this example, the pointer to the header file has been omitted,\n 00142 * so we need to append the binary file system ourselves (see above).\n 00143 * When you use the binary file system header in your main file, you can\n 00144 * use the roFlashDrive pointer.\n 00145 * eg (for a KL25Z device) : static FlashFileSystem flash("flash", roFlashDrive, 128);\n 00146 *\n 00147 * NOTE: This file system is case-sensitive. Calling fopen("/flash/INDEX.html")\n 00148 * won't successfully open a file named index.html in the root directory\n 00149 * of the flash file system.\n 00150 * 00151 * Example: 00152 * @code 00153 #include <mbed.h> 00154 #include "FlashFileSystem.h" 00155 // Uncomment the line below when you imported the header file built with fsbld 00156 // and replace <Flashdrive> with its correct filename 00157 //#include "<FlashDrive>.h" 00158 00159 static void _RecursiveDir(const char* pDirectoryName, DIR* pDirectory = NULL) 00160 { 00161 DIR* pFreeDirectory = NULL; 00162 00163 size_t DirectoryNameLength = strlen(pDirectoryName); 00164 00165 // Open the specified directory. 00166 if (!pDirectory) 00167 { 00168 pDirectory = opendir(pDirectoryName); 00169 if (!pDirectory) 00170 { 00171 error("Failed to open directory '%s' for enumeration.\r\n", 00172 pDirectoryName); 00173 } 00174 00175 // Remember to free this directory enumerator. 00176 pFreeDirectory = pDirectory; 00177 } 00178 00179 // Determine if we should remove a trailing slash from future *printf() 00180 // calls. 00181 if (DirectoryNameLength && '/' == pDirectoryName[DirectoryNameLength-1]) 00182 { 00183 DirectoryNameLength--; 00184 } 00185 00186 // Iterate though each item contained within this directory and display 00187 // it to the console. 00188 struct dirent* DirEntry; 00189 while((DirEntry = readdir(pDirectory)) != NULL) 00190 { 00191 char RecurseDirectoryName[256]; 00192 DIR* pSubdirectory; 00193 00194 // Try opening this file as a directory to see if it succeeds or not. 00195 snprintf(RecurseDirectoryName, sizeof(RecurseDirectoryName), 00196 "%.*s/%s", 00197 DirectoryNameLength, 00198 pDirectoryName, 00199 DirEntry->d_name); 00200 pSubdirectory = opendir(RecurseDirectoryName); 00201 00202 if (pSubdirectory) 00203 { 00204 _RecursiveDir(RecurseDirectoryName, pSubdirectory); 00205 closedir(pSubdirectory); 00206 } 00207 else 00208 { 00209 printf(" %.*s/%s\n", 00210 DirectoryNameLength, 00211 pDirectoryName, 00212 DirEntry->d_name); 00213 } 00214 } 00215 00216 // Close the directory enumerator if it was opened by this call. 00217 if (pFreeDirectory) 00218 { 00219 closedir(pFreeDirectory); 00220 } 00221 } 00222 00223 int main() 00224 { 00225 static const char* Filename = "/flash/index.html"; 00226 char* ReadResult = NULL; 00227 int SeekResult = -1; 00228 char Buffer[128]; 00229 00230 // Create the file system under the name "flash". 00231 // NOTE : When you include the the header file built with fsbld, 00232 // disable the first static FlashFileSystem... line 00233 // and enable the second static FlashFileSystem... line. 00234 static FlashFileSystem flash("flash"); 00235 // static FlashFileSystem flash("flash, roFlashDrive"); 00236 if (!flash.IsMounted()) 00237 { 00238 error("Failed to mount FlashFileSystem.\r\n"); 00239 } 00240 00241 // Open "index.html" on the file system for reading. 00242 FILE *fp = fopen(Filename, "r"); 00243 if (NULL == fp) 00244 { 00245 error("Failed to open %s\r\n", Filename); 00246 } 00247 00248 // Use seek to determine the length of the file 00249 SeekResult = fseek(fp, 0, SEEK_END); 00250 if (SeekResult) 00251 { 00252 error("Failed to seek to end of %s.\r\n", Filename); 00253 } 00254 long FileLength = ftell(fp); 00255 printf("%s is %ld bytes in length.\r\n", Filename, FileLength); 00256 00257 // Reset the file pointer to the beginning of the file 00258 SeekResult = fseek(fp, 0, SEEK_SET); 00259 if (SeekResult) 00260 { 00261 error("Failed to seek to beginning of %s.\r\n", Filename); 00262 } 00263 00264 // Read the first line into Buffer and then display to user. 00265 ReadResult = fgets(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), fp); 00266 if (NULL == ReadResult) 00267 { 00268 error("Failed to read first line of %s.\r\n", Filename); 00269 } 00270 printf("%s:1 %s", Filename, Buffer); 00271 00272 // Done with the file so close it. 00273 fclose(fp); 00274 00275 // Enumerate all content on mounted file systems. 00276 printf("\r\nList all files in /flash...\r\n"); 00277 _RecursiveDir("/flash"); 00278 00279 printf("\r\nFlashFileSystem example has completed.\r\n"); 00280 } 00281 * @endcode 00282 */ 00283 class FlashFileSystem : public FileSystemLike 00284 { 00285 public: 00286 FlashFileSystem(const char* pName, const uint8_t *pFlashDrive = NULL, const uint32_t FlashSize = 512); 00287 00288 virtual FileHandle* open(const char* pFilename, int Flags); 00289 virtual DirHandle* opendir(const char *pDirectoryName); 00290 00291 virtual int IsMounted() { return (m_FileCount != 0); } 00292 00293 protected: 00294 FlashFileSystemFileHandle* FindFreeFileHandle(); 00295 FlashFileSystemDirHandle* FindFreeDirHandle(); 00296 00297 // File handle table used by this file system so that it doesn't need 00298 // to dynamically allocate file handles at runtime. 00299 FlashFileSystemFileHandle m_FileHandles[16]; 00300 // Directory handle table used by this file system so that it doesn't need 00301 // to dynamically allocate file handles at runtime. 00302 FlashFileSystemDirHandle m_DirHandles[16]; 00303 // Pointer to where the file system image is located in the device's FLASH. 00304 const char* m_pFLASHBase; 00305 // Pointer to where the file entries are located in the device's FLASH. 00306 const _SFileSystemEntry* m_pFileEntries; 00307 // The number of files in the file system image. 00308 unsigned int m_FileCount; 00309 }; 00310 00311 #endif // _FLASHFILESYSTEM_H_
Generated on Tue Jul 12 2022 18:57:29 by 1.7.2