mFS file system library for EEPROM memory chips.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mfs.h Source File

mfs.h

Go to the documentation of this file.
00001 /** @file mfs.h */ 
00002 /*H****************************************************************************
00003  * FILENAME :        mfs.h                                                    *
00004  *                                                                            *
00005  * DESCRIPTION :                                                              *
00006  *       mFS file system implementation for mBED with external I2C EEEPROM.   *
00007  *                                                                            *
00008  * ---------------------------------------------------------------------------*
00009  * "THE BEER-WARE LICENSE" (Revision 42):                                     *
00010  * <olli.vanhoja@gmail.com> wrote this file. As long as you retain this notice*
00011  * you can do whatever you want with this stuff. If we meet some day, and you *
00012  * think this stuff is worth it, you can buy me a beer in return Olli Vanhoja *
00013  * ---------------------------------------------------------------------------*
00014  *                                                                            *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
00019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
00020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
00021  * DEALINGS IN THE SOFTWARE.                                                  *
00022  *                                                                            *
00023  *                                                                            *
00024  * Block Flags:                                                               *
00025  * 7:FBOF      Begining of file                                               *
00026  * 6:LBOF      Last block of file                                             *
00027  * 5:RO        Read only file (Used only with FBOF)                           *
00028  * 4:HIDDEN    Hidden file (Used only with FBOF)                              *
00029  * 3:INUSE     Block in use                                                   *
00030  * 2:NBAD      Bad block (INV)                                                *
00031  * 1:VOL       Volume label (Used only with FBOF)                             *
00032  * 0:LOCK      Locked file (Used only with FBOF)                              *
00033  *                                                                            *
00034  * AUTHOR :         Olli Vanhoja       START DATE :    2011-02-18             *
00035  ******************************************************************************
00036  *
00037  * CHANGES :
00038  *
00039  * VERSION DATE       WHO            DETAIL
00040  * 0.1     2011-02-21 Olli Vanhoja   Initial release version
00041  * 0.2     2011-02-21 Olli Vanhoja   Documentational comments added
00042  * 0.3     2011-02-21 Olli Vanhoja   * File::read issues fixed, rewind/forward
00043  *                                     functions improved
00044  *                                   * Added possibility change I2C speed
00045  *                                   * I2C autoreset on failure
00046  * 0.4     2011-02-22 Olli Vanhoja   * mfs::renameFile(char [20], char [20] function added
00047  *                                   * Incresed fault tolerance by first allocating new
00048  *                                     block and then linking to it from previous block
00049  *                                   * Reconstructed initialization and use of some variables
00050  * 0.5     2011-02-22 Olli Vanhoja   * Improved documentation
00051  *                                   * Block variables changed from char to uint32_t for
00052  *                                     code optimization (and for possible 16bit update which
00053  *                                     would technically allow 256 TB volume sizes)
00054  *                                   * Optimized file searching algorithms
00055  * 0.6     2011-02-22 Olli Vanhoja   * Fixed file remove issue
00056  *                                   * Fixed mkfs bug
00057  * 0.7     2011-02-23 Olli Vanhoja   * file::seek(uint32_t) added
00058  * 0.7     2011-02-23 Olli Vanhoja   * Fixed destroying prev link issue on flush
00059  *                                   * Fixed Forwarding issue which moved cursor at the begining
00060  *                                     of the filename block
00061  *                                   * Separated locating of next/prev links functionality
00062  *                                     into its own private function
00063  *                                   * 16 bit block number pointers 256 TB theoretical maximum
00064  *                                     volume size, WHOA \O/
00065  *                                   * Remove and rename respects RO bit
00066  *                                   * SetFileFlags fixed
00067  *                                   * New file write mode DWRITE
00068  * 0.8     2011-02-24 Olli Vanhoja   * EOF should be now found in AWRITE mode and EOF is
00069  *                                   * also written by mfs::createFile() so there should
00070  *                                     be no more confusing situations with new files.
00071  *
00072  * TODO :
00073  *          * Directory support (VOL blocks?)
00074  *          * RAID 0 & 1
00075  *H*/
00076 
00077 #ifndef MFS_H
00078 #define MFS_H
00079 
00080 #include "i2c_eeprom.h"
00081 
00082 const unsigned int VOL_SIZE=65536; /**< EEPROM chip size in bytes */
00083 const unsigned int BS=1024; /**< How many bytes per block (default: 4096 bytes) */
00084 const unsigned int BC=VOL_SIZE / BS; // block count
00085 const char mEOF='\x01'; // End Of File/Section marked
00086 const unsigned int BUF=400; /**< File buffer length */
00087 
00088 /** mFS File System class
00089  * 
00090  * This class is used as a handle for the fs in use.
00091  */
00092 class mfs {
00093 private:
00094     i2c_eeprom *mem; // Only 512 kB I2C EEPROM is supported ATM
00095 public:
00096     /** Create a new file system object
00097     *
00098     * @param xi2c_address a Physical I2C address of the EEPROM chip  
00099     */
00100     mfs(int i2c_address);
00101     
00102     /** Read data from specified fs block
00103     *
00104     * @param *data Pointer for readed data
00105     * @param block Block number.
00106     * @param byte Selected byte.
00107     * @param n Bytes to be read.
00108     * @returns Error code: 0 = OK, 1 = Incorrect input
00109     */
00110     char read(char *data, uint32_t block, uint32_t byte, uint32_t n);
00111     
00112     /** Write data to specified fs block
00113     *
00114     * @param *data Pointer for readed data
00115     * @param block Block number.
00116     * @param byte Selected byte.
00117     * @param n Bytes to be read.
00118     * @returns Error code: 0 = OK, 1 = Incorrect input
00119     */
00120     char write(char *data, uint32_t block, uint32_t byte, uint32_t n);
00121     
00122     /** Locate next free block
00123     *
00124     * @param *blockOut Returns next free block from begining of the fs.
00125     * @returns Error code: 0 = OK, 1 = Out of space
00126     */
00127     char getNextFreeBlock(uint32_t *blockOut);
00128     
00129     /** Locates next starting file from parameter block
00130     *
00131     * @param block Start scanning from this block.
00132     * @param *filenameOut Return name of the file found.
00133     * @param Returns block number of the file found.
00134     * @returns Error code: 0 = OK, 1 = Empty fs
00135     */
00136     char findNextFile(uint32_t block, char *filenameOut, uint32_t *blockOut);
00137     
00138     /** Get block number of the given file
00139     *
00140     * Returns block number of the block flaged with FBOF flag.
00141     *
00142     * @param filename[20] Filename input.
00143     * @param Returns block number of the first block of the given file.
00144     * @returns Error code: 0 = OK, 1 = File not found
00145     */
00146     char getFirstBlockOfFile(char filename[20], uint32_t *blockOut);
00147     
00148     /** Create a new empty file
00149     *
00150     * Reserves one block for the file created.
00151     *
00152     * @param filename[20] Filename input.
00153     * @returns Error code: 0 = OK, 1 = File exists already, 2 = Out of space
00154     */
00155     char createFile(char filename[20]);
00156     
00157     /** Remove a file from the file system
00158     *
00159     * @param filename[20] Filename input.
00160     * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = RO file
00161     */
00162     char removeFile(char filename[20]);
00163     
00164     /** Rename a file
00165     *
00166     * @param oldFilename[20] Old filename.
00167     * @param newFilename[20] New file name.
00168     * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = RO file, 3 = fs is corrupted
00169     */
00170     char renameFile(char oldFilename[20], char newFilename[20]);
00171     
00172     /** Set user modifiable flags.
00173     *
00174     * \code
00175     * desc RO|HIDDEN|LOCK
00176     * bit  3    2       1
00177     * \endcode
00178     *
00179     * @param *flags Flag input
00180     * @param filename[20] Filename input.
00181     * @returns Error code: 0 = OK, 1 = File doesn't exists, 2 = File system is corrupted
00182     */
00183     char setFileFlags(char *flags, char filename[20]);
00184     
00185     /** Read user modifiable flags.
00186     *
00187     * \code
00188     * desc RO|HIDDEN|LOCK
00189     * bit  3    2       1
00190     * \endcode
00191     *
00192     * @param *flags Flag output
00193     * @param filename[20] Filename input.
00194     * @returns Error code: 0 = OK, 1 = File doesn't exists
00195     */
00196     char getFileFlags(char *flags, char filename[20]);
00197     
00198     /** Get number of free blocks
00199     *
00200     * @returns Number of free blocks.
00201     */
00202     uint32_t free();
00203     
00204     /** Format new file system
00205     *
00206     * \note Keep in mind that only first byte is checked for functionality and
00207     * if it's broken the who file system is useless.
00208     *
00209     * @param createLabel Create volume label at the begining of the file system. (there is no specified use for volume labels atm).
00210     * @returns Number of bad block headers.
00211     */
00212     uint32_t mkfs(bool createLabel);
00213 };
00214 
00215 enum BlockLinkType {NEXT, PREV};
00216 enum FileOpenMode {RO, AWRITE, DWRITE};
00217 
00218 /** mFS File handle class
00219  * 
00220  * This class provides a file handle and data manipulation methods to be
00221  * used for files stored in mFS files system.
00222  */
00223 class file {
00224 private:
00225     mfs *fs;   // Reference to the file system in use
00226     FileOpenMode fMode;
00227     char buffer[BUF]; // Write buffer
00228     uint32_t bufPos; // "Cursor" position in buffer
00229     uint32_t firstBlock; // First block of the file
00230     uint32_t currBlock; // Current block in use
00231     uint32_t blockPos; // "head" position on the current block
00232     uint32_t byteCount; // Stores current "cursor" position in file for seek
00233     // Private functions
00234     char getBlockLink(BlockLinkType linkSelection, uint32_t *blockOut);
00235     char removeFollowingBlocks(uint32_t block); // Offers destructive write/very simple wear levelling
00236 public:
00237     /** Create file handle
00238     *
00239     * \warning File must be created before it can be opened!
00240     * Opening non-existing file will trip the system to error();
00241     * If read only file is opened in rw mode system will trip to error().
00242     *
00243     * \b AWRITE is a file access mode where cursor can be moved along the file
00244     * and write can be started at any point. write() function will overwrite
00245     * only as many bytes as you chosen to write.
00246     *
00247     * \b DWRITE is a file access mode similiar to AWRITE but when you start
00248     * writing all the data after cursor will be removed permanently and flush()
00249     * will set a new EOF marker.
00250     *
00251     * @param filename[20] Filename input.
00252     * @param operation RO = Read only, AWRITE = read and write, DWRITE = read + destructive write.
00253     */
00254     file(mfs *fs_ref, char filename[20], FileOpenMode operation);
00255     
00256     /** Close file handle
00257     *
00258     * Flushes the file and closes the handle.
00259     */
00260     ~file(); // Close file handle and flush
00261     
00262     /** Rewind to the start postion of the file
00263     *
00264     */
00265     void rewind();
00266     
00267     /** Reverse n bytes back
00268     *
00269     * @param n Number of bytes.
00270     * @returns Error code: 0 = OK, 1 = First byte of file.
00271     */
00272     char rewind(uint32_t n);
00273     
00274     /** Forward one byte
00275     *
00276     * @returns Error code: 0 = OK, 1 = End of file.
00277     */
00278     char forward();
00279     
00280     /** Forward n bytes
00281     *
00282     * @param n Number of blocks.
00283     * @returns Error code: 0 = OK, 1 = End of file.
00284     */
00285     char forward(uint32_t n);
00286     
00287     /** Seek to byte given
00288     *
00289     * @param byte Byte number where to seek.
00290     * @returns Error code: 0 = OK, 1 = End of file or already at first byte.
00291     */
00292     char seek(uint32_t byte);
00293     
00294     /** Reads a string of bytes
00295     *
00296     * Always places '\0' at the end of string.
00297     *
00298     * @param data Output buffer.
00299     * @param n Number of bytes to be read.
00300     * @returns Error code. 0 = OK, 1 = Last block of the file
00301     */
00302     void read(char *data, uint32_t n);
00303     
00304     /** Reads a binary array of bytes
00305     *
00306     * Doesn't add '\0' at the end of data array and doesn't respect mEOF byte.
00307     *
00308     * @param data Output buffer.
00309     * @param n Number of bytes to be read.
00310     */   
00311     void readBin(char *data, uint32_t n);
00312     
00313     /** Write byte array to a file (buffer)
00314     *
00315     * @param data Input data.
00316     * @param n Number of bytes to be read.
00317     * @returns Error code: 0 = OK, 1 = Flush failed.
00318     */    
00319     char write(char *data, uint32_t n);
00320     
00321     /** Flush file buffer
00322     * Writes buffer to the EEPROM chip in use.
00323     *
00324     * @returns Error code: 0 = OK, 1 = Out of free space, 2 = Destructive operation failed (fs is corrupted).
00325     */
00326     char flush();
00327 };
00328 
00329 #endif