mFS file system library for EEPROM memory chips.

Committer:
HBP
Date:
Thu Feb 24 09:28:32 2011 +0000
Revision:
13:142b6be3e3c8
Parent:
12:928346513c87
- Better handling of empty files
- doesn\t write EOF on AWRITE if EOF is not reached

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HBP 5:a0fe74dce80d 1 /** @file mfs.h */
HBP 0:cbf45dde2b49 2 /*H****************************************************************************
HBP 7:5ac5121bb4e0 3 * FILENAME : mfs.h *
HBP 7:5ac5121bb4e0 4 * *
HBP 7:5ac5121bb4e0 5 * DESCRIPTION : *
HBP 7:5ac5121bb4e0 6 * mFS file system implementation for mBED with external I2C EEEPROM. *
HBP 8:e67733ad4427 7 * *
HBP 8:e67733ad4427 8 * ---------------------------------------------------------------------------*
HBP 8:e67733ad4427 9 * "THE BEER-WARE LICENSE" (Revision 42): *
HBP 8:e67733ad4427 10 * <olli.vanhoja@gmail.com> wrote this file. As long as you retain this notice*
HBP 8:e67733ad4427 11 * you can do whatever you want with this stuff. If we meet some day, and you *
HBP 8:e67733ad4427 12 * think this stuff is worth it, you can buy me a beer in return Olli Vanhoja *
HBP 8:e67733ad4427 13 * ---------------------------------------------------------------------------*
HBP 8:e67733ad4427 14 * *
HBP 8:e67733ad4427 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
HBP 8:e67733ad4427 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
HBP 8:e67733ad4427 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
HBP 8:e67733ad4427 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
HBP 8:e67733ad4427 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
HBP 8:e67733ad4427 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
HBP 8:e67733ad4427 21 * DEALINGS IN THE SOFTWARE. *
HBP 8:e67733ad4427 22 * *
HBP 8:e67733ad4427 23 * *
HBP 8:e67733ad4427 24 * Block Flags: *
HBP 8:e67733ad4427 25 * 7:FBOF Begining of file *
HBP 8:e67733ad4427 26 * 6:LBOF Last block of file *
HBP 8:e67733ad4427 27 * 5:RO Read only file (Used only with FBOF) *
HBP 8:e67733ad4427 28 * 4:HIDDEN Hidden file (Used only with FBOF) *
HBP 8:e67733ad4427 29 * 3:INUSE Block in use *
HBP 8:e67733ad4427 30 * 2:NBAD Bad block (INV) *
HBP 8:e67733ad4427 31 * 1:VOL Volume label (Used only with FBOF) *
HBP 8:e67733ad4427 32 * 0:LOCK Locked file (Used only with FBOF) *
HBP 8:e67733ad4427 33 * *
HBP 8:e67733ad4427 34 * AUTHOR : Olli Vanhoja START DATE : 2011-02-18 *
HBP 8:e67733ad4427 35 ******************************************************************************
HBP 7:5ac5121bb4e0 36 *
HBP 7:5ac5121bb4e0 37 * CHANGES :
HBP 7:5ac5121bb4e0 38 *
HBP 7:5ac5121bb4e0 39 * VERSION DATE WHO DETAIL
HBP 7:5ac5121bb4e0 40 * 0.1 2011-02-21 Olli Vanhoja Initial release version
HBP 7:5ac5121bb4e0 41 * 0.2 2011-02-21 Olli Vanhoja Documentational comments added
HBP 10:211cb54339a0 42 * 0.3 2011-02-21 Olli Vanhoja * File::read issues fixed, rewind/forward
HBP 10:211cb54339a0 43 * functions improved
HBP 10:211cb54339a0 44 * * Added possibility change I2C speed
HBP 10:211cb54339a0 45 * * I2C autoreset on failure
HBP 10:211cb54339a0 46 * 0.4 2011-02-22 Olli Vanhoja * mfs::renameFile(char [20], char [20] function added
HBP 10:211cb54339a0 47 * * Incresed fault tolerance by first allocating new
HBP 10:211cb54339a0 48 * block and then linking to it from previous block
HBP 10:211cb54339a0 49 * * Reconstructed initialization and use of some variables
HBP 10:211cb54339a0 50 * 0.5 2011-02-22 Olli Vanhoja * Improved documentation
HBP 10:211cb54339a0 51 * * Block variables changed from char to uint32_t for
HBP 10:211cb54339a0 52 * code optimization (and for possible 16bit update which
HBP 11:6c4fcb9d6193 53 * would technically allow 256 TB volume sizes)
HBP 10:211cb54339a0 54 * * Optimized file searching algorithms
HBP 11:6c4fcb9d6193 55 * 0.6 2011-02-22 Olli Vanhoja * Fixed file remove issue
HBP 12:928346513c87 56 * * Fixed mkfs bug
HBP 12:928346513c87 57 * 0.7 2011-02-23 Olli Vanhoja * file::seek(uint32_t) added
HBP 12:928346513c87 58 * 0.7 2011-02-23 Olli Vanhoja * Fixed destroying prev link issue on flush
HBP 12:928346513c87 59 * * Fixed Forwarding issue which moved cursor at the begining
HBP 12:928346513c87 60 * of the filename block
HBP 12:928346513c87 61 * * Separated locating of next/prev links functionality
HBP 12:928346513c87 62 * into its own private function
HBP 12:928346513c87 63 * * 16 bit block number pointers 256 TB theoretical maximum
HBP 12:928346513c87 64 * volume size, WHOA \O/
HBP 12:928346513c87 65 * * Remove and rename respects RO bit
HBP 12:928346513c87 66 * * SetFileFlags fixed
HBP 12:928346513c87 67 * * New file write mode DWRITE
HBP 13:142b6be3e3c8 68 * 0.8 2011-02-24 Olli Vanhoja * EOF should be now found in AWRITE mode and EOF is
HBP 13:142b6be3e3c8 69 * * also written by mfs::createFile() so there should
HBP 13:142b6be3e3c8 70 * be no more confusing situations with new files.
HBP 7:5ac5121bb4e0 71 *
HBP 7:5ac5121bb4e0 72 * TODO :
HBP 10:211cb54339a0 73 * * Directory support (VOL blocks?)
HBP 12:928346513c87 74 * * RAID 0 & 1
HBP 7:5ac5121bb4e0 75 *H*/
HBP 0:cbf45dde2b49 76
HBP 0:cbf45dde2b49 77 #ifndef MFS_H
HBP 0:cbf45dde2b49 78 #define MFS_H
HBP 0:cbf45dde2b49 79
HBP 0:cbf45dde2b49 80 #include "i2c_eeprom.h"
HBP 0:cbf45dde2b49 81
HBP 6:dd3346914d42 82 const unsigned int VOL_SIZE=65536; /**< EEPROM chip size in bytes */
HBP 6:dd3346914d42 83 const unsigned int BS=1024; /**< How many bytes per block (default: 4096 bytes) */
HBP 10:211cb54339a0 84 const unsigned int BC=VOL_SIZE / BS; // block count
HBP 0:cbf45dde2b49 85 const char mEOF='\x01'; // End Of File/Section marked
HBP 6:dd3346914d42 86 const unsigned int BUF=400; /**< File buffer length */
HBP 0:cbf45dde2b49 87
HBP 3:1cbc15648de1 88 /** mFS File System class
HBP 3:1cbc15648de1 89 *
HBP 3:1cbc15648de1 90 * This class is used as a handle for the fs in use.
HBP 3:1cbc15648de1 91 */
HBP 0:cbf45dde2b49 92 class mfs {
HBP 0:cbf45dde2b49 93 private:
HBP 0:cbf45dde2b49 94 i2c_eeprom *mem; // Only 512 kB I2C EEPROM is supported ATM
HBP 0:cbf45dde2b49 95 public:
HBP 3:1cbc15648de1 96 /** Create a new file system object
HBP 3:1cbc15648de1 97 *
HBP 3:1cbc15648de1 98 * @param xi2c_address a Physical I2C address of the EEPROM chip
HBP 3:1cbc15648de1 99 */
HBP 0:cbf45dde2b49 100 mfs(int i2c_address);
HBP 5:a0fe74dce80d 101
HBP 10:211cb54339a0 102 /** Read data from specified fs block
HBP 3:1cbc15648de1 103 *
HBP 3:1cbc15648de1 104 * @param *data Pointer for readed data
HBP 3:1cbc15648de1 105 * @param block Block number.
HBP 3:1cbc15648de1 106 * @param byte Selected byte.
HBP 3:1cbc15648de1 107 * @param n Bytes to be read.
HBP 10:211cb54339a0 108 * @returns Error code: 0 = OK, 1 = Incorrect input
HBP 3:1cbc15648de1 109 */
HBP 10:211cb54339a0 110 char read(char *data, uint32_t block, uint32_t byte, uint32_t n);
HBP 5:a0fe74dce80d 111
HBP 10:211cb54339a0 112 /** Write data to specified fs block
HBP 3:1cbc15648de1 113 *
HBP 3:1cbc15648de1 114 * @param *data Pointer for readed data
HBP 3:1cbc15648de1 115 * @param block Block number.
HBP 3:1cbc15648de1 116 * @param byte Selected byte.
HBP 3:1cbc15648de1 117 * @param n Bytes to be read.
HBP 10:211cb54339a0 118 * @returns Error code: 0 = OK, 1 = Incorrect input
HBP 3:1cbc15648de1 119 */
HBP 10:211cb54339a0 120 char write(char *data, uint32_t block, uint32_t byte, uint32_t n);
HBP 5:a0fe74dce80d 121
HBP 3:1cbc15648de1 122 /** Locate next free block
HBP 3:1cbc15648de1 123 *
HBP 3:1cbc15648de1 124 * @param *blockOut Returns next free block from begining of the fs.
HBP 10:211cb54339a0 125 * @returns Error code: 0 = OK, 1 = Out of space
HBP 3:1cbc15648de1 126 */
HBP 10:211cb54339a0 127 char getNextFreeBlock(uint32_t *blockOut);
HBP 5:a0fe74dce80d 128
HBP 3:1cbc15648de1 129 /** Locates next starting file from parameter block
HBP 3:1cbc15648de1 130 *
HBP 3:1cbc15648de1 131 * @param block Start scanning from this block.
HBP 3:1cbc15648de1 132 * @param *filenameOut Return name of the file found.
HBP 10:211cb54339a0 133 * @param Returns block number of the file found.
HBP 10:211cb54339a0 134 * @returns Error code: 0 = OK, 1 = Empty fs
HBP 3:1cbc15648de1 135 */
HBP 10:211cb54339a0 136 char findNextFile(uint32_t block, char *filenameOut, uint32_t *blockOut);
HBP 5:a0fe74dce80d 137
HBP 10:211cb54339a0 138 /** Get block number of the given file
HBP 10:211cb54339a0 139 *
HBP 10:211cb54339a0 140 * Returns block number of the block flaged with FBOF flag.
HBP 3:1cbc15648de1 141 *
HBP 3:1cbc15648de1 142 * @param filename[20] Filename input.
HBP 10:211cb54339a0 143 * @param Returns block number of the first block of the given file.
HBP 10:211cb54339a0 144 * @returns Error code: 0 = OK, 1 = File not found
HBP 3:1cbc15648de1 145 */
HBP 10:211cb54339a0 146 char getFirstBlockOfFile(char filename[20], uint32_t *blockOut);
HBP 5:a0fe74dce80d 147
HBP 4:c77812997c9c 148 /** Create a new empty file
HBP 3:1cbc15648de1 149 *
HBP 3:1cbc15648de1 150 * Reserves one block for the file created.
HBP 3:1cbc15648de1 151 *
HBP 3:1cbc15648de1 152 * @param filename[20] Filename input.
HBP 10:211cb54339a0 153 * @returns Error code: 0 = OK, 1 = File exists already, 2 = Out of space
HBP 3:1cbc15648de1 154 */
HBP 0:cbf45dde2b49 155 char createFile(char filename[20]);
HBP 5:a0fe74dce80d 156
HBP 10:211cb54339a0 157 /** Remove a file from the file system
HBP 3:1cbc15648de1 158 *
HBP 3:1cbc15648de1 159 * @param filename[20] Filename input.
HBP 12:928346513c87 160 * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = RO file
HBP 3:1cbc15648de1 161 */
HBP 0:cbf45dde2b49 162 char removeFile(char filename[20]);
HBP 5:a0fe74dce80d 163
HBP 10:211cb54339a0 164 /** Rename a file
HBP 7:5ac5121bb4e0 165 *
HBP 10:211cb54339a0 166 * @param oldFilename[20] Old filename.
HBP 10:211cb54339a0 167 * @param newFilename[20] New file name.
HBP 12:928346513c87 168 * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = RO file, 3 = fs is corrupted
HBP 7:5ac5121bb4e0 169 */
HBP 7:5ac5121bb4e0 170 char renameFile(char oldFilename[20], char newFilename[20]);
HBP 7:5ac5121bb4e0 171
HBP 3:1cbc15648de1 172 /** Set user modifiable flags.
HBP 3:1cbc15648de1 173 *
HBP 10:211cb54339a0 174 * \code
HBP 3:1cbc15648de1 175 * desc RO|HIDDEN|LOCK
HBP 3:1cbc15648de1 176 * bit 3 2 1
HBP 10:211cb54339a0 177 * \endcode
HBP 3:1cbc15648de1 178 *
HBP 3:1cbc15648de1 179 * @param *flags Flag input
HBP 3:1cbc15648de1 180 * @param filename[20] Filename input.
HBP 10:211cb54339a0 181 * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = File system is corrupted
HBP 3:1cbc15648de1 182 */
HBP 0:cbf45dde2b49 183 char setFileFlags(char *flags, char filename[20]);
HBP 5:a0fe74dce80d 184
HBP 3:1cbc15648de1 185 /** Read user modifiable flags.
HBP 3:1cbc15648de1 186 *
HBP 10:211cb54339a0 187 * \code
HBP 3:1cbc15648de1 188 * desc RO|HIDDEN|LOCK
HBP 3:1cbc15648de1 189 * bit 3 2 1
HBP 10:211cb54339a0 190 * \endcode
HBP 3:1cbc15648de1 191 *
HBP 3:1cbc15648de1 192 * @param *flags Flag output
HBP 3:1cbc15648de1 193 * @param filename[20] Filename input.
HBP 10:211cb54339a0 194 * @returns Error code: 0 = OK, 1 = File doesn't exists
HBP 3:1cbc15648de1 195 */
HBP 0:cbf45dde2b49 196 char getFileFlags(char *flags, char filename[20]);
HBP 5:a0fe74dce80d 197
HBP 3:1cbc15648de1 198 /** Get number of free blocks
HBP 3:1cbc15648de1 199 *
HBP 3:1cbc15648de1 200 * @returns Number of free blocks.
HBP 3:1cbc15648de1 201 */
HBP 10:211cb54339a0 202 uint32_t free();
HBP 5:a0fe74dce80d 203
HBP 3:1cbc15648de1 204 /** Format new file system
HBP 3:1cbc15648de1 205 *
HBP 10:211cb54339a0 206 * \note Keep in mind that only first byte is checked for functionality and
HBP 10:211cb54339a0 207 * if it's broken the who file system is useless.
HBP 3:1cbc15648de1 208 *
HBP 3:1cbc15648de1 209 * @param createLabel Create volume label at the begining of the file system. (there is no specified use for volume labels atm).
HBP 10:211cb54339a0 210 * @returns Number of bad block headers.
HBP 3:1cbc15648de1 211 */
HBP 10:211cb54339a0 212 uint32_t mkfs(bool createLabel);
HBP 0:cbf45dde2b49 213 };
HBP 0:cbf45dde2b49 214
HBP 12:928346513c87 215 enum BlockLinkType {NEXT, PREV};
HBP 12:928346513c87 216 enum FileOpenMode {RO, AWRITE, DWRITE};
HBP 12:928346513c87 217
HBP 4:c77812997c9c 218 /** mFS File handle class
HBP 4:c77812997c9c 219 *
HBP 10:211cb54339a0 220 * This class provides a file handle and data manipulation methods to be
HBP 10:211cb54339a0 221 * used for files stored in mFS files system.
HBP 4:c77812997c9c 222 */
HBP 0:cbf45dde2b49 223 class file {
HBP 0:cbf45dde2b49 224 private:
HBP 0:cbf45dde2b49 225 mfs *fs; // Reference to the file system in use
HBP 12:928346513c87 226 FileOpenMode fMode;
HBP 0:cbf45dde2b49 227 char buffer[BUF]; // Write buffer
HBP 9:52c01cb100ac 228 uint32_t bufPos; // "Cursor" position in buffer
HBP 12:928346513c87 229 uint32_t firstBlock; // First block of the file
HBP 12:928346513c87 230 uint32_t currBlock; // Current block in use
HBP 9:52c01cb100ac 231 uint32_t blockPos; // "head" position on the current block
HBP 12:928346513c87 232 uint32_t byteCount; // Stores current "cursor" position in file for seek
HBP 12:928346513c87 233 // Private functions
HBP 12:928346513c87 234 char getBlockLink(BlockLinkType linkSelection, uint32_t *blockOut);
HBP 12:928346513c87 235 char removeFollowingBlocks(uint32_t block); // Offers destructive write/very simple wear levelling
HBP 0:cbf45dde2b49 236 public:
HBP 10:211cb54339a0 237 /** Create file handle
HBP 3:1cbc15648de1 238 *
HBP 10:211cb54339a0 239 * \warning File must be created before it can be opened!
HBP 10:211cb54339a0 240 * Opening non-existing file will trip the system to error();
HBP 10:211cb54339a0 241 * If read only file is opened in rw mode system will trip to error().
HBP 3:1cbc15648de1 242 *
HBP 12:928346513c87 243 * \b AWRITE is a file access mode where cursor can be moved along the file
HBP 12:928346513c87 244 * and write can be started at any point. write() function will overwrite
HBP 12:928346513c87 245 * only as many bytes as you chosen to write.
HBP 12:928346513c87 246 *
HBP 12:928346513c87 247 * \b DWRITE is a file access mode similiar to AWRITE but when you start
HBP 12:928346513c87 248 * writing all the data after cursor will be removed permanently and flush()
HBP 12:928346513c87 249 * will set a new EOF marker.
HBP 12:928346513c87 250 *
HBP 3:1cbc15648de1 251 * @param filename[20] Filename input.
HBP 12:928346513c87 252 * @param operation RO = Read only, AWRITE = read and write, DWRITE = read + destructive write.
HBP 3:1cbc15648de1 253 */
HBP 12:928346513c87 254 file(mfs *fs_ref, char filename[20], FileOpenMode operation);
HBP 5:a0fe74dce80d 255
HBP 3:1cbc15648de1 256 /** Close file handle
HBP 3:1cbc15648de1 257 *
HBP 3:1cbc15648de1 258 * Flushes the file and closes the handle.
HBP 3:1cbc15648de1 259 */
HBP 0:cbf45dde2b49 260 ~file(); // Close file handle and flush
HBP 5:a0fe74dce80d 261
HBP 3:1cbc15648de1 262 /** Rewind to the start postion of the file
HBP 5:a0fe74dce80d 263 *
HBP 3:1cbc15648de1 264 */
HBP 3:1cbc15648de1 265 void rewind();
HBP 5:a0fe74dce80d 266
HBP 12:928346513c87 267 /** Reverse n bytes back
HBP 5:a0fe74dce80d 268 *
HBP 12:928346513c87 269 * @param n Number of bytes.
HBP 12:928346513c87 270 * @returns Error code: 0 = OK, 1 = First byte of file.
HBP 5:a0fe74dce80d 271 */
HBP 9:52c01cb100ac 272 char rewind(uint32_t n);
HBP 5:a0fe74dce80d 273
HBP 5:a0fe74dce80d 274 /** Forward one byte
HBP 5:a0fe74dce80d 275 *
HBP 10:211cb54339a0 276 * @returns Error code: 0 = OK, 1 = End of file.
HBP 3:1cbc15648de1 277 */
HBP 3:1cbc15648de1 278 char forward();
HBP 5:a0fe74dce80d 279
HBP 5:a0fe74dce80d 280 /** Forward n bytes
HBP 5:a0fe74dce80d 281 *
HBP 5:a0fe74dce80d 282 * @param n Number of blocks.
HBP 10:211cb54339a0 283 * @returns Error code: 0 = OK, 1 = End of file.
HBP 5:a0fe74dce80d 284 */
HBP 9:52c01cb100ac 285 char forward(uint32_t n);
HBP 5:a0fe74dce80d 286
HBP 12:928346513c87 287 /** Seek to byte given
HBP 12:928346513c87 288 *
HBP 12:928346513c87 289 * @param byte Byte number where to seek.
HBP 12:928346513c87 290 * @returns Error code: 0 = OK, 1 = End of file or already at first byte.
HBP 12:928346513c87 291 */
HBP 12:928346513c87 292 char seek(uint32_t byte);
HBP 12:928346513c87 293
HBP 3:1cbc15648de1 294 /** Reads a string of bytes
HBP 3:1cbc15648de1 295 *
HBP 3:1cbc15648de1 296 * Always places '\0' at the end of string.
HBP 3:1cbc15648de1 297 *
HBP 3:1cbc15648de1 298 * @param data Output buffer.
HBP 3:1cbc15648de1 299 * @param n Number of bytes to be read.
HBP 5:a0fe74dce80d 300 * @returns Error code. 0 = OK, 1 = Last block of the file
HBP 3:1cbc15648de1 301 */
HBP 9:52c01cb100ac 302 void read(char *data, uint32_t n);
HBP 12:928346513c87 303
HBP 3:1cbc15648de1 304 /** Reads a binary array of bytes
HBP 3:1cbc15648de1 305 *
HBP 3:1cbc15648de1 306 * Doesn't add '\0' at the end of data array and doesn't respect mEOF byte.
HBP 3:1cbc15648de1 307 *
HBP 3:1cbc15648de1 308 * @param data Output buffer.
HBP 3:1cbc15648de1 309 * @param n Number of bytes to be read.
HBP 12:928346513c87 310 */
HBP 12:928346513c87 311 void readBin(char *data, uint32_t n);
HBP 5:a0fe74dce80d 312
HBP 3:1cbc15648de1 313 /** Write byte array to a file (buffer)
HBP 3:1cbc15648de1 314 *
HBP 3:1cbc15648de1 315 * @param data Input data.
HBP 3:1cbc15648de1 316 * @param n Number of bytes to be read.
HBP 10:211cb54339a0 317 * @returns Error code: 0 = OK, 1 = Flush failed.
HBP 12:928346513c87 318 */
HBP 9:52c01cb100ac 319 char write(char *data, uint32_t n);
HBP 5:a0fe74dce80d 320
HBP 3:1cbc15648de1 321 /** Flush file buffer
HBP 3:1cbc15648de1 322 * Writes buffer to the EEPROM chip in use.
HBP 12:928346513c87 323 *
HBP 12:928346513c87 324 * @returns Error code: 0 = OK, 1 = Out of free space, 2 = Destructive operation failed (fs is corrupted).
HBP 3:1cbc15648de1 325 */
HBP 0:cbf45dde2b49 326 char flush();
HBP 0:cbf45dde2b49 327 };
HBP 0:cbf45dde2b49 328
HBP 0:cbf45dde2b49 329 #endif