mFS file system library for EEPROM memory chips.

Revision:
10:211cb54339a0
Parent:
9:52c01cb100ac
Child:
11:6c4fcb9d6193
--- a/mfs.cpp	Tue Feb 22 18:57:37 2011 +0000
+++ b/mfs.cpp	Tue Feb 22 21:09:04 2011 +0000
@@ -1,3 +1,4 @@
+/** @file mfs.cpp */
 /*CPP**************************************************************************
  * FILENAME :        mfs.cpp                                                  *
  *                                                                            *
@@ -11,17 +12,19 @@
 #include "mfs.h"
 #include "i2c_eeprom.h"
 
-#define RB 3 // Reseved bytes per block (1 attrb B, 2 B for next/prev pointers
-#define DEBUG // Adds extra safety to reading and writing
+#define BLOCK_NLEN 1 /**< Block number length in bytes */
+#define RB 1+2*BLOCK_NLEN /**< Reseved bytes per block (1 attrb B, 2 B for next/prev pointers */
+#define I2C_SPEED 200000 /**< I2C bus speed in Hz */
+#define DEBUG /**< Adds extra safety in reading and writing */
 
-DigitalOut FlushLed(LED2);
+DigitalOut FlushLed(LED2); /**< Flush led */
 
 mfs::mfs(int i2c_address)
 {
-    mem = new i2c_eeprom(i2c_address, 200000);
+    mem = new i2c_eeprom(i2c_address, I2C_SPEED);
 }
 
-char mfs::read(char *data, char block, uint32_t byte, uint32_t n)
+char mfs::read(char *data, uint32_t block, uint32_t byte, uint32_t n)
 {
     // Faster reading without DEBUG mode
     #ifdef DEBUG
@@ -33,7 +36,7 @@
     return 0;
 }
 
-char mfs::write(char *data, char block, uint32_t byte, uint32_t n)
+char mfs::write(char *data, uint32_t block, uint32_t byte, uint32_t n)
 {
     // Faster writing without DEBUG mode
     #ifdef DEBUG
@@ -44,7 +47,7 @@
     return 0;
 }
 
-char mfs::getNextFreeBlock(char *blockOut)
+char mfs::getNextFreeBlock(uint32_t *blockOut)
 {    
     // Locate free block by seeking EERPOM
     char cFlags[1];
@@ -61,7 +64,7 @@
     return 0;
 }
 
-uint32_t mfs::findNextFile(char block, char *filenameOut)
+char mfs::findNextFile(uint32_t block, char *filenameOut, uint32_t *blockOut)
 {
     uint32_t i=block;
     char cFlags[1];
@@ -79,44 +82,41 @@
     if(i == BC)
     {
         strcpy(filenameOut, "");
-        return 0xffff; // Empty fs
+        return 1; // Empty fs
     }
     
     // Read filename
-    read(filenameOut, i, 3, 20);
-    return i; // Return block number
+    read(filenameOut, i, RB, 20);
+    *blockOut = i; // Return block number
+    return 0;
 }
 
-uint32_t mfs::getFirstBlockOfFile(char filename[20])
+char mfs::getFirstBlockOfFile(char filename[20], uint32_t *blockOut)
 {
-    uint32_t block=0;
+    *blockOut=0;
     char tmpFilename[20]="";
 
-    while (block < BC)
+    while (1)
     {
-        block = findNextFile(block, tmpFilename);
-        if (block < BC)
+        if (findNextFile(*blockOut, tmpFilename, blockOut) == 0)
         {
             if(strcmp(tmpFilename, filename) == 0)
-               return block; // File exists
+                return 0; // File exists
         }
-        else return 0xFFFF; // File doesn't exist
-        block++;
+        else return 1; // File doesn't exist
+        (*blockOut)++;
     }
-
-    return 0xFFFF; // ??
 }
 
 char mfs::createFile(char filename[20])
 {
     char tmpFilename[20];
     uint32_t n;
-    char fb;
+    uint32_t fb;
 
     for (n=0; n < BC; n++)
     {
-        n=findNextFile(n, tmpFilename);
-        if(n < BC)
+        if(findNextFile(n, tmpFilename, &n) == 0)
         {
             if(strcmp(tmpFilename, filename) == 0)
                 return 1; // File exist
@@ -125,19 +125,19 @@
         n++;
     }
 
-    if(getNextFreeBlock(&fb))
+    if(getNextFreeBlock(&fb) != 0)
         return 2; // Out of space
     
-    char cData[23];
+    char cData[RB+20];
     cData[0] = '\xCC'; // Necessary flags for file
     cData[1] = '\0'; // Only this block yet
     cData[2] = '\0'; // First block there could't be prev blocks
     
     for (char i=0; i < 20; i++)
-        cData[3+i] = filename[i];
+        cData[RB+i] = filename[i];
     
     // Create file
-    write(cData, fb, 0, 23);
+    write(cData, fb, 0, RB+20);
         
     return 0;
 }
@@ -148,8 +148,7 @@
     char cData[3] = {'\0','\0','\0'};
 
     // Check if file exists
-    block = getFirstBlockOfFile(filename);
-    if (block > BC)
+    if (getFirstBlockOfFile(filename, &block) == 0)
         return 1; // File not found
     
     // Clear blocks reserver by the file
@@ -182,11 +181,10 @@
     uint32_t block;
 
     // Check if file exists
-    block = getFirstBlockOfFile(oldFilename);
-    if (block > BC)
+    if (getFirstBlockOfFile(oldFilename, &block) != 0)
         return 1; // File not found
     
-    write(newFilename, block, 3, 20);
+    write(newFilename, block, RB, 20);
     
     return 0; // Everything went better than expected
 }
@@ -200,8 +198,7 @@
     char cData[1] = {'\0'};
 
     // Check if file exists
-    n = getFirstBlockOfFile(filename);
-    if (n > BC)
+    if (getFirstBlockOfFile(filename, &n) != 0)
         return 1; // File not found
     
     read(cData, n, 0, 1);
@@ -220,8 +217,7 @@
     char cData[1] = {'\0'};
 
     // Check if file exists
-    n = getFirstBlockOfFile(filename);
-    if (n > BC)
+    if (getFirstBlockOfFile(filename, &n) != 0)
         return 1; // File not found
     
     read(cData, n, 0, 1);
@@ -231,10 +227,10 @@
 }
 
 // Return number of free blocks
-char mfs::free()
+uint32_t mfs::free()
 {
-    char blocks=0;
-    char r;
+    uint32_t blocks=0;
+    uint32_t r;
     char cFlags[1];
     
     for (r=0; r < BC; r++)
@@ -249,14 +245,14 @@
     return 0;
 }
 
-char mfs::mkfs(char createLabel)
+uint32_t mfs::mkfs(bool createLabel)
 {
-    unsigned int iAddr = 0;
-    char i = 0;
-    char bad = 0; // For counting bad block headers
+    uint32_t iAddr = 0;
+    uint32_t i = 0;
+    uint32_t bad = 0; // For counting bad block headers
     char cFlags[] = {'\0', '\0', '\0'}, a[1];
     
-    if (createLabel >= 1)
+    if (createLabel == true)
     {
         // Write Volume label
         cFlags[0] = '\x0E';
@@ -291,8 +287,7 @@
     char cData[3] = {'\0','\0','\0'};
 
     // Check if file exists
-    n = fs->getFirstBlockOfFile(filename);
-    if (n == 0xFFFF)
+    if (fs->getFirstBlockOfFile(filename, &n) != 0)
         error("Oops, file \"%s\" not found! n=0x%X", filename, n); // File not found
     
     fs->read(cData, n, 0, 1);
@@ -342,19 +337,16 @@
         if (blockPos < 3)
         {
             // Fetch link to next block
-            fs->read(cData, currBlock, 0, 3);
+            fs->read(cData, currBlock, 0, RB);
             if (!(cData[0] & 0x80))
             {
                 currBlock = cData[2];
                 blockPos = BS-1; // Set block postion offset at end of the block
             } else {
                 blockPos++;
-                return 1; // This is the last block
+                return 1; // This is the first block
             }
         }
-        fs->read(cData, currBlock, blockPos, 1);
-        if (cData[0] == mEOF)
-            return 1;
     }
     
     return 0; // OK
@@ -392,7 +384,10 @@
         }
         fs->read(cData, currBlock, blockPos, 1);
         if (cData[0] == mEOF)
+        {
+            rewind(1);
             return 1;
+        }
     }
     
     return 0; // OK
@@ -490,7 +485,7 @@
 char file::flush()
 {
     char cData[3], c[1];
-    char nextFree;
+    uint32_t nextFree;
     uint32_t i;
     
     if (bufPos == 0) return 0; // File up-to date
@@ -514,14 +509,14 @@
             cData[0] = 0x4C; // New flags
             cData[1] = '\0';
             cData[2] = currBlock; // Prev Block
-            fs->write(cData, nextFree, 0, 3); // Update Block Data
+            fs->write(cData, nextFree, 0, RB); // Update Block Data
             
             // Link old block with new block
-            fs->read(cData, currBlock, 0, 3);
+            fs->read(cData, currBlock, 0, RB);
             cData[0] &= ~0x40; // Clear LBOF flag if set
             cData[1] = nextFree;
             cData[2] = '\0';
-            fs->write(cData, currBlock, 0, 3); // Update Block Data
+            fs->write(cData, currBlock, 0, RB); // Update Block Data
             
             // Update current block info
             currBlock = nextFree;