FATFileSystem

Dependents:   SDFileSystem IPS SDFileSystem SDFileSystem ... more

Fork of FATFileSystem by mbed official

Files at this revision

API Documentation at this revision

Comitter:
screamer
Date:
Mon Mar 17 14:09:00 2014 +0000
Parent:
2:b6669c987c8e
Child:
4:3ff2606d5713
Commit message:
Added code documentation and fixed compile warning

Changed in this revision

ChaN/ff.cpp Show annotated file Show diff for this revision Revisions of this file
FATFileSystem.h Show annotated file Show diff for this revision Revisions of this file
MemFileSystem.h Show annotated file Show diff for this revision Revisions of this file
--- a/ChaN/ff.cpp	Thu Nov 29 10:56:08 2012 +0000
+++ b/ChaN/ff.cpp	Mon Mar 17 14:09:00 2014 +0000
@@ -527,14 +527,16 @@
 
 /* Copy memory to memory */
 static
-void mem_cpy (void* dst, const void* src, UINT cnt) {
+void mem_cpy (void* dst, const void* src, UINT cnt)
+{
     BYTE *d = (BYTE*)dst;
     const BYTE *s = (const BYTE*)src;
 
 #if _WORD_ACCESS == 1
     while (cnt >= sizeof (int)) {
         *(int*)d = *(int*)s;
-        d += sizeof (int); s += sizeof (int);
+        d += sizeof (int);
+        s += sizeof (int);
         cnt -= sizeof (int);
     }
 #endif
@@ -544,7 +546,8 @@
 
 /* Fill memory */
 static
-void mem_set (void* dst, int val, UINT cnt) {
+void mem_set (void* dst, int val, UINT cnt)
+{
     BYTE *d = (BYTE*)dst;
 
     while (cnt--)
@@ -553,7 +556,8 @@
 
 /* Compare memory to memory */
 static
-int mem_cmp (const void* dst, const void* src, UINT cnt) {
+int mem_cmp (const void* dst, const void* src, UINT cnt)
+{
     const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;
     int r = 0;
 
@@ -563,7 +567,8 @@
 
 /* Check if chr is contained in the string */
 static
-int chk_chr (const char* str, int chr) {
+int chk_chr (const char* str, int chr)
+{
     while (*str && *str != chr) str++;
     return *str;
 }
@@ -591,10 +596,10 @@
 )
 {
     if (fs &&
-        res != FR_NOT_ENABLED &&
-        res != FR_INVALID_DRIVE &&
-        res != FR_INVALID_OBJECT &&
-        res != FR_TIMEOUT) {
+            res != FR_NOT_ENABLED &&
+            res != FR_INVALID_DRIVE &&
+            res != FR_INVALID_OBJECT &&
+            res != FR_TIMEOUT) {
         ff_rel_grant(fs->sobj);
     }
 }
@@ -619,8 +624,8 @@
     for (i = be = 0; i < _FS_LOCK; i++) {
         if (Files[i].fs) {  /* Existing entry */
             if (Files[i].fs == dj->fs &&        /* Check if the file matched with an open file */
-                Files[i].clu == dj->sclust &&
-                Files[i].idx == dj->index) break;
+                    Files[i].clu == dj->sclust &&
+                    Files[i].idx == dj->index) break;
         } else {            /* Blank entry */
             be++;
         }
@@ -654,8 +659,8 @@
 
     for (i = 0; i < _FS_LOCK; i++) {    /* Find the file */
         if (Files[i].fs == dj->fs &&
-            Files[i].clu == dj->sclust &&
-            Files[i].idx == dj->index) break;
+                Files[i].clu == dj->sclust &&
+                Files[i].idx == dj->index) break;
     }
 
     if (i == _FS_LOCK) {                /* Not opened. Register it as new. */
@@ -831,23 +836,25 @@
         return 1;
 
     switch (fs->fs_type) {
-    case FS_FAT12 :
-        bc = (UINT)clst; bc += bc / 2;
-        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
-        wc = fs->win[bc % SS(fs)]; bc++;
-        if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
-        wc |= fs->win[bc % SS(fs)] << 8;
-        return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
-
-    case FS_FAT16 :
-        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
-        p = &fs->win[clst * 2 % SS(fs)];
-        return LD_WORD(p);
-
-    case FS_FAT32 :
-        if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
-        p = &fs->win[clst * 4 % SS(fs)];
-        return LD_DWORD(p) & 0x0FFFFFFF;
+        case FS_FAT12 :
+            bc = (UINT)clst;
+            bc += bc / 2;
+            if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
+            wc = fs->win[bc % SS(fs)];
+            bc++;
+            if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
+            wc |= fs->win[bc % SS(fs)] << 8;
+            return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
+
+        case FS_FAT16 :
+            if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
+            p = &fs->win[clst * 2 % SS(fs)];
+            return LD_WORD(p);
+
+        case FS_FAT32 :
+            if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
+            p = &fs->win[clst * 4 % SS(fs)];
+            return LD_DWORD(p) & 0x0FFFFFFF;
     }
 
     return 0xFFFFFFFF;  /* An error occurred at the disk I/O layer */
@@ -877,37 +884,38 @@
 
     } else {
         switch (fs->fs_type) {
-        case FS_FAT12 :
-            bc = (UINT)clst; bc += bc / 2;
-            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
-            if (res != FR_OK) break;
-            p = &fs->win[bc % SS(fs)];
-            *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
-            bc++;
-            fs->wflag = 1;
-            res = move_window(fs, fs->fatbase + (bc / SS(fs)));
-            if (res != FR_OK) break;
-            p = &fs->win[bc % SS(fs)];
-            *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
-            break;
-
-        case FS_FAT16 :
-            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
-            if (res != FR_OK) break;
-            p = &fs->win[clst * 2 % SS(fs)];
-            ST_WORD(p, (WORD)val);
-            break;
-
-        case FS_FAT32 :
-            res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
-            if (res != FR_OK) break;
-            p = &fs->win[clst * 4 % SS(fs)];
-            val |= LD_DWORD(p) & 0xF0000000;
-            ST_DWORD(p, val);
-            break;
-
-        default :
-            res = FR_INT_ERR;
+            case FS_FAT12 :
+                bc = (UINT)clst;
+                bc += bc / 2;
+                res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+                if (res != FR_OK) break;
+                p = &fs->win[bc % SS(fs)];
+                *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
+                bc++;
+                fs->wflag = 1;
+                res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+                if (res != FR_OK) break;
+                p = &fs->win[bc % SS(fs)];
+                *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
+                break;
+
+            case FS_FAT16 :
+                res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
+                if (res != FR_OK) break;
+                p = &fs->win[clst * 2 % SS(fs)];
+                ST_WORD(p, (WORD)val);
+                break;
+
+            case FS_FAT32 :
+                res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
+                if (res != FR_OK) break;
+                p = &fs->win[clst * 4 % SS(fs)];
+                val |= LD_DWORD(p) & 0xF0000000;
+                ST_DWORD(p, val);
+                break;
+
+            default :
+                res = FR_INT_ERR;
         }
         fs->wflag = 1;
     }
@@ -943,8 +951,14 @@
         while (clst < fs->n_fatent) {           /* Not a last link? */
             nxt = get_fat(fs, clst);            /* Get cluster status */
             if (nxt == 0) break;                /* Empty cluster? */
-            if (nxt == 1) { res = FR_INT_ERR; break; }  /* Internal error? */
-            if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }    /* Disk error? */
+            if (nxt == 1) {
+                res = FR_INT_ERR;    /* Internal error? */
+                break;
+            }
+            if (nxt == 0xFFFFFFFF) {
+                res = FR_DISK_ERR;    /* Disk error? */
+                break;
+            }
             res = put_fat(fs, clst, 0);         /* Mark the cluster "empty" */
             if (res != FR_OK) break;
             if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */
@@ -989,8 +1003,7 @@
     if (clst == 0) {        /* Create a new chain */
         scl = fs->last_clust;           /* Get suggested start point */
         if (!scl || scl >= fs->n_fatent) scl = 1;
-    }
-    else {                  /* Stretch the current chain */
+    } else {                /* Stretch the current chain */
         cs = get_fat(fs, clst);         /* Check the cluster status */
         if (cs < 2) return 1;           /* It is an invalid cluster */
         if (cs < fs->n_fatent) return cs;   /* It is already followed by next cluster */
@@ -1051,7 +1064,8 @@
         ncl = *tbl++;           /* Number of cluters in the fragment */
         if (!ncl) return 0;     /* End of table? (error) */
         if (cl < ncl) break;    /* In this fragment? */
-        cl -= ncl; tbl++;       /* Next fragment */
+        cl -= ncl;
+        tbl++;       /* Next fragment */
     }
     return cl + *tbl;   /* Return the cluster number */
 }
@@ -1085,8 +1099,7 @@
         if (idx >= dj->fs->n_rootdir)       /* Index is out of range */
             return FR_INT_ERR;
         dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR);   /* Sector# */
-    }
-    else {              /* Dynamic table (sub-dirs or root-dir in FAT32) */
+    } else {            /* Dynamic table (sub-dirs or root-dir in FAT32) */
         ic = SS(dj->fs) / SZ_DIR * dj->fs->csize;   /* Entries per cluster */
         while (idx >= ic) { /* Follow cluster chain */
             clst = get_fat(dj->fs, clst);               /* Get next cluster */
@@ -1132,8 +1145,7 @@
         if (dj->clust == 0) {   /* Static table */
             if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */
                 return FR_NO_FILE;
-        }
-        else {                  /* Dynamic table */
+        } else {                /* Dynamic table */
             if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */
                 clst = get_fat(dj->fs, dj->clust);              /* Get next cluster */
                 if (clst <= 1) return FR_INT_ERR;
@@ -1228,7 +1240,8 @@
 
 
     i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13;  /* Get offset in the LFN buffer */
-    s = 0; wc = 1;
+    s = 0;
+    wc = 1;
     do {
         uc = LD_WORD(dir+LfnOfs[s]);    /* Pick an LFN character from the entry */
         if (wc) {   /* Last char has not been processed */
@@ -1260,7 +1273,8 @@
 
     i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;  /* Offset in the LFN buffer */
 
-    s = 0; wc = 1;
+    s = 0;
+    wc = 1;
     do {
         uc = LD_WORD(dir+LfnOfs[s]);        /* Pick an LFN character from the entry */
         if (wc) {   /* Last char has not been processed */
@@ -1332,7 +1346,8 @@
     mem_cpy(dst, src, 11);
 
     if (seq > 5) {  /* On many collisions, generate a hash number instead of sequential number */
-        do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn);
+        do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++;
+        while (*lfn);
     }
 
     /* itoa (hexdecimal) */
@@ -1373,7 +1388,8 @@
     BYTE sum = 0;
     UINT n = 11;
 
-    do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
+    do sum = (sum >> 1) + (sum << 7) + *dir++;
+    while (--n);
     return sum;
 }
 #endif
@@ -1407,7 +1423,10 @@
         if (res != FR_OK) break;
         dir = dj->dir;                  /* Ptr to the directory entry of current index */
         c = dir[DIR_Name];
-        if (c == 0) { res = FR_NO_FILE; break; }    /* Reached to end of table */
+        if (c == 0) {
+            res = FR_NO_FILE;    /* Reached to end of table */
+            break;
+        }
 #if _USE_LFN    /* LFN configuration */
         a = dir[DIR_Attr] & AM_MASK;
         if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) {    /* An entry without valid data */
@@ -1417,7 +1436,8 @@
                 if (dj->lfn) {
                     if (c & LLE) {      /* Is it start of LFN sequence? */
                         sum = dir[LDIR_Chksum];
-                        c &= ~LLE; ord = c; /* LFN start order */
+                        c &= ~LLE;
+                        ord = c; /* LFN start order */
                         dj->lfn_idx = dj->index;
                     }
                     /* Check validity of the LFN entry and compare it with given name */
@@ -1425,7 +1445,8 @@
                 }
             } else {                    /* An SFN entry is found */
                 if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */
-                ord = 0xFF; dj->lfn_idx = 0xFFFF;   /* Reset LFN sequence */
+                ord = 0xFF;
+                dj->lfn_idx = 0xFFFF;   /* Reset LFN sequence */
                 if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break;    /* SFN matched? */
             }
         }
@@ -1463,7 +1484,10 @@
         if (res != FR_OK) break;
         dir = dj->dir;                  /* Ptr to the directory entry of current index */
         c = dir[DIR_Name];
-        if (c == 0) { res = FR_NO_FILE; break; }    /* Reached to end of table */
+        if (c == 0) {
+            res = FR_NO_FILE;    /* Reached to end of table */
+            break;
+        }
 #if _USE_LFN    /* LFN configuration */
         a = dir[DIR_Attr] & AM_MASK;
         if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) {    /* An entry without valid data */
@@ -1472,7 +1496,8 @@
             if (a == AM_LFN) {          /* An LFN entry is found */
                 if (c & LLE) {          /* Is it start of LFN sequence? */
                     sum = dir[LDIR_Chksum];
-                    c &= ~LLE; ord = c;
+                    c &= ~LLE;
+                    ord = c;
                     dj->lfn_idx = dj->index;
                 }
                 /* Check LFN validity and capture it */
@@ -1516,14 +1541,16 @@
     WCHAR *lfn;
 
 
-    fn = dj->fn; lfn = dj->lfn;
+    fn = dj->fn;
+    lfn = dj->lfn;
     mem_cpy(sn, fn, 12);
 
     if (_FS_RPATH && (sn[NS] & NS_DOT))     /* Cannot create dot entry */
         return FR_INVALID_NAME;
 
     if (sn[NS] & NS_LOSS) {         /* When LFN is out of 8.3 format, generate a numbered name */
-        fn[NS] = 0; dj->lfn = 0;            /* Find only SFN */
+        fn[NS] = 0;
+        dj->lfn = 0;            /* Find only SFN */
         for (n = 1; n < 100; n++) {
             gen_numname(fn, sn, lfn, n);    /* Generate a numbered name */
             res = dir_find(dj);             /* Check if the name collides with existing SFN */
@@ -1531,7 +1558,8 @@
         }
         if (n == 100) return FR_DENIED;     /* Abort if too many collisions */
         if (res != FR_NO_FILE) return res;  /* Abort if the result is other than 'not collided' */
-        fn[NS] = sn[NS]; dj->lfn = lfn;
+        fn[NS] = sn[NS];
+        dj->lfn = lfn;
     }
 
     if (sn[NS] & NS_LFN) {          /* When LFN is to be created, reserve an SFN + LFN entries. */
@@ -1686,7 +1714,8 @@
             b = (BYTE)p[si++];          /* Get 2nd byte */
             if (!IsDBCS2(b))
                 return FR_INVALID_NAME; /* Reject invalid sequence */
-            w = (w << 8) + b;           /* Create a DBC */
+            else
+                w = (w << 8) + b;           /* Create a DBC */
         }
         w = ff_convert(w, 1);           /* Convert ANSI/OEM to Unicode */
         if (!w) return FR_INVALID_NAME; /* Reject invalid code */
@@ -1699,7 +1728,7 @@
     cf = (w < ' ') ? NS_LAST : 0;       /* Set last segment flag if end of path */
 #if _FS_RPATH
     if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */
-        (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
+            (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {
         lfn[di] = 0;
         for (i = 0; i < 11; i++)
             dj->fn[i] = (i < di) ? '.' : ' ';
@@ -1722,22 +1751,28 @@
     if (si) cf |= NS_LOSS | NS_LFN;
     while (di && lfn[di - 1] != '.') di--;  /* Find extension (di<=si: no extension) */
 
-    b = i = 0; ni = 8;
+    b = i = 0;
+    ni = 8;
     for (;;) {
         w = lfn[si++];                  /* Get an LFN char */
         if (!w) break;                  /* Break on end of the LFN */
         if (w == ' ' || (w == '.' && si != di)) {   /* Remove spaces and dots */
-            cf |= NS_LOSS | NS_LFN; continue;
+            cf |= NS_LOSS | NS_LFN;
+            continue;
         }
 
         if (i >= ni || si == di) {      /* Extension or end of SFN */
             if (ni == 11) {             /* Long extension */
-                cf |= NS_LOSS | NS_LFN; break;
+                cf |= NS_LOSS | NS_LFN;
+                break;
             }
             if (si != di) cf |= NS_LOSS | NS_LFN;   /* Out of 8.3 format */
             if (si > di) break;         /* No extension */
-            si = di; i = 8; ni = 11;    /* Enter extension section */
-            b <<= 2; continue;
+            si = di;
+            i = 8;
+            ni = 11;    /* Enter extension section */
+            b <<= 2;
+            continue;
         }
 
         if (w >= 0x80) {                /* Non ASCII char */
@@ -1752,18 +1787,22 @@
 
         if (_DF1S && w >= 0x100) {      /* Double byte char (always false on SBCS cfg) */
             if (i >= ni - 1) {
-                cf |= NS_LOSS | NS_LFN; i = ni; continue;
+                cf |= NS_LOSS | NS_LFN;
+                i = ni;
+                continue;
             }
             dj->fn[i++] = (BYTE)(w >> 8);
         } else {                        /* Single byte char */
             if (!w || chk_chr("+,;=[]", w)) {   /* Replace illegal chars for SFN */
-                w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
+                w = '_';
+                cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
             } else {
                 if (IsUpper(w)) {       /* ASCII large capital */
                     b |= 2;
                 } else {
                     if (IsLower(w)) {   /* ASCII small capital */
-                        b |= 1; w -= 0x20;
+                        b |= 1;
+                        w -= 0x20;
                     }
                 }
             }
@@ -1795,7 +1834,8 @@
     for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */
     sfn = dj->fn;
     mem_set(sfn, ' ', 11);
-    si = i = b = 0; ni = 8;
+    si = i = b = 0;
+    ni = 8;
 #if _FS_RPATH
     if (p[si] == '.') { /* Is this a dot entry? */
         for (;;) {
@@ -1814,8 +1854,10 @@
         if (c <= ' ' || c == '/' || c == '\\') break;   /* Break on end of segment */
         if (c == '.' || i >= ni) {
             if (ni != 8 || c != '.') return FR_INVALID_NAME;
-            i = 8; ni = 11;
-            b <<= 2; continue;
+            i = 8;
+            ni = 11;
+            b <<= 2;
+            continue;
         }
         if (c >= 0x80) {                /* Extended char? */
             b |= 3;                     /* Eliminate NT flag */
@@ -1840,7 +1882,8 @@
                 b |= 2;
             } else {
                 if (IsLower(c)) {       /* ASCII small capital? */
-                    b |= 1; c -= 0x20;
+                    b |= 1;
+                    c -= 0x20;
                 }
             }
             sfn[i++] = c;
@@ -1930,11 +1973,17 @@
             while ((w = *lfn++) != 0) {         /* Get an LFN char */
 #if !_LFN_UNICODE
                 w = ff_convert(w, 0);           /* Unicode -> OEM conversion */
-                if (!w) { i = 0; break; }       /* Could not convert, no LFN */
+                if (!w) {
+                    i = 0;    /* Could not convert, no LFN */
+                    break;
+                }
                 if (_DF1S && w >= 0x100)        /* Put 1st byte if it is a DBC (always false on SBCS cfg) */
                     tp[i++] = (TCHAR)(w >> 8);
 #endif
-                if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */
+                if (i >= fno->lfsize - 1) {
+                    i = 0;    /* Buffer overflow, no LFN */
+                    break;
+                }
                 tp[i++] = (TCHAR)w;
             }
         }
@@ -1963,7 +2012,8 @@
 
 #if _FS_RPATH
     if (*path == '/' || *path == '\\') { /* There is a heading separator */
-        path++; dj->sclust = 0;     /* Strip it and start from the root dir */
+        path++;
+        dj->sclust = 0;     /* Strip it and start from the root dir */
     } else {                            /* No heading separator */
         dj->sclust = dj->fs->cdir;  /* Start from the current dir */
     }
@@ -1986,7 +2036,8 @@
                 if (res != FR_NO_FILE) break;   /* Abort if any hard error occurred */
                 /* Object not found */
                 if (_FS_RPATH && (ns & NS_DOT)) {   /* If dot entry is not exit */
-                    dj->sclust = 0; dj->dir = 0;    /* It is the root dir */
+                    dj->sclust = 0;
+                    dj->dir = 0;    /* It is the root dir */
                     res = FR_OK;
                     if (!(ns & NS_LAST)) continue;
                 } else {                            /* Could not find the object */
@@ -1997,7 +2048,8 @@
             if (ns & NS_LAST) break;            /* Last segment match. Function completed. */
             dir = dj->dir;                      /* There is next segment. Follow the sub directory */
             if (!(dir[DIR_Attr] & AM_DIR)) {    /* Cannot follow because it is a file */
-                res = FR_NO_PATH; break;
+                res = FR_NO_PATH;
+                break;
             }
             dj->sclust = ld_clust(dj->fs, dir);
         }
@@ -2058,7 +2110,8 @@
     /* Get logical drive number from the path name */
     vol = p[0] - '0';                   /* Is there a drive number? */
     if (vol <= 9 && p[1] == ':') {      /* Found a drive number, get and strip it */
-        p += 2; *path = p;              /* Return pointer to the path name */
+        p += 2;
+        *path = p;              /* Return pointer to the path name */
     } else {                            /* No drive number is given */
 #if _FS_RPATH
         vol = CurrVol;                  /* Use current drive */
@@ -2162,7 +2215,7 @@
         if (!fs->n_rootdir) return FR_NO_FILESYSTEM;    /* (BPB_RootEntCnt must not be 0) */
         fs->dirbase = fs->fatbase + fasize;             /* Root directory start sector */
         szbfat = (fmt == FS_FAT16) ?                    /* (Required FAT size) */
-            fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
+                 fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
     }
     if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))   /* (BPB_FATSz must not be less than required) */
         return FR_NO_FILESYSTEM;
@@ -2177,11 +2230,11 @@
         fs->fsi_flag = 0;
         fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
         if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&
-            LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
-            LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
-            LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
-                fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
-                fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
+                LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
+                LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
+                LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
+            fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
+            fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
         }
     }
 #endif
@@ -2329,8 +2382,7 @@
 #endif
                 mode |= FA_CREATE_ALWAYS;       /* File is created */
                 dir = dj.dir;                   /* New entry */
-            }
-            else {                              /* Any object is already existing */
+            } else {                            /* Any object is already existing */
                 if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {    /* Cannot overwrite it (R/O or DIR) */
                     res = FR_DENIED;
                 } else {
@@ -2355,8 +2407,7 @@
                     }
                 }
             }
-        }
-        else {  /* Open an existing file */
+        } else { /* Open an existing file */
             if (res == FR_OK) {                     /* Follow succeeded */
                 if (dir[DIR_Attr] & AM_DIR) {       /* It is a directory */
                     res = FR_NO_FILE;
@@ -2399,7 +2450,8 @@
 #if _USE_FASTSEEK
             fp->cltbl = 0;                      /* Normal seek mode */
 #endif
-            fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
+            fp->fs = dj.fs;
+            fp->id = dj.fs->id; /* Validate file object */
         }
     }
 
@@ -2438,7 +2490,7 @@
     if (btr > remain) btr = (UINT)remain;       /* Truncate btr by remaining bytes */
 
     for ( ;  btr;                               /* Repeat until all data read */
-        rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
+            rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
         if ((fp->fptr % SS(fp->fs)) == 0) {     /* On the sector boundary? */
             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
             if (!csect) {                       /* On the cluster boundary? */
@@ -2539,7 +2591,7 @@
     if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0;  /* File size cannot reach 4GB */
 
     for ( ;  btw;                           /* Repeat until all data written */
-        wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
+            wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
         if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
             if (!csect) {                   /* On the cluster boundary? */
@@ -2601,8 +2653,8 @@
 #else
             if (fp->dsect != sect) {        /* Fill sector cache with file data */
                 if (fp->fptr < fp->fsize &&
-                    disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
-                        ABORT(fp->fs, FR_DISK_ERR);
+                        disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
+                    ABORT(fp->fs, FR_DISK_ERR);
             }
 #endif
             fp->dsect = sect;
@@ -2817,7 +2869,8 @@
             if (_USE_LFN && *path) tp = path;
             for (n = 0; tp[n]; n++) ;
             if (i < n + 3) {
-                res = FR_NOT_ENOUGH_CORE; break;
+                res = FR_NOT_ENOUGH_CORE;
+                break;
             }
             while (n) path[--i] = tp[--n];
             path[--i] = '/';
@@ -2869,20 +2922,25 @@
 
         if (ofs == CREATE_LINKMAP) {    /* Create CLMT */
             tbl = fp->cltbl;
-            tlen = *tbl++; ulen = 2;    /* Given table size and required table size */
+            tlen = *tbl++;
+            ulen = 2;    /* Given table size and required table size */
             cl = fp->sclust;            /* Top of the chain */
             if (cl) {
                 do {
                     /* Get a fragment */
-                    tcl = cl; ncl = 0; ulen += 2;   /* Top, length and used items */
+                    tcl = cl;
+                    ncl = 0;
+                    ulen += 2;   /* Top, length and used items */
                     do {
-                        pcl = cl; ncl++;
+                        pcl = cl;
+                        ncl++;
                         cl = get_fat(fp->fs, cl);
                         if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
                         if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                     } while (cl == pcl + 1);
                     if (ulen <= tlen) {     /* Store the length and top of the fragment */
-                        *tbl++ = ncl; *tbl++ = tcl;
+                        *tbl++ = ncl;
+                        *tbl++ = tcl;
                     }
                 } while (cl < fp->fs->n_fatent);    /* Repeat until end of chain */
             }
@@ -2920,22 +2978,22 @@
     } else
 #endif
 
-    /* Normal Seek */
+        /* Normal Seek */
     {
         DWORD clst, bcs, nsect, ifptr;
 
         if (ofs > fp->fsize                 /* In read-only mode, clip offset with the file size */
 #if !_FS_READONLY
-             && !(fp->flag & FA_WRITE)
+                && !(fp->flag & FA_WRITE)
 #endif
-            ) ofs = fp->fsize;
+           ) ofs = fp->fsize;
 
         ifptr = fp->fptr;
         fp->fptr = nsect = 0;
         if (ofs) {
             bcs = (DWORD)fp->fs->csize * SS(fp->fs);    /* Cluster size (byte) */
             if (ifptr > 0 &&
-                (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
+                    (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
                 fp->fptr = (ifptr - 1) & ~(bcs - 1);    /* start from the current cluster */
                 ofs -= fp->fptr;
                 clst = fp->clust;
@@ -2957,7 +3015,8 @@
                     if (fp->flag & FA_WRITE) {          /* Check if in write mode or not */
                         clst = create_chain(fp->fs, clst);  /* Force stretch if in write mode */
                         if (clst == 0) {                /* When disk gets full, clip file size */
-                            ofs = bcs; break;
+                            ofs = bcs;
+                            break;
                         }
                     } else
 #endif
@@ -3158,14 +3217,21 @@
                 clst = 2;
                 do {
                     stat = get_fat(fs, clst);
-                    if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
-                    if (stat == 1) { res = FR_INT_ERR; break; }
+                    if (stat == 0xFFFFFFFF) {
+                        res = FR_DISK_ERR;
+                        break;
+                    }
+                    if (stat == 1) {
+                        res = FR_INT_ERR;
+                        break;
+                    }
                     if (stat == 0) n++;
                 } while (++clst < fs->n_fatent);
             } else {
                 clst = fs->n_fatent;
                 sect = fs->fatbase;
-                i = 0; p = 0;
+                i = 0;
+                p = 0;
                 do {
                     if (!i) {
                         res = move_window(fs, sect++);
@@ -3175,10 +3241,12 @@
                     }
                     if (fat == FS_FAT16) {
                         if (LD_WORD(p) == 0) n++;
-                        p += 2; i -= 2;
+                        p += 2;
+                        i -= 2;
                     } else {
                         if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
-                        p += 4; i -= 4;
+                        p += 4;
+                        i -= 4;
                     }
                 } while (--clst);
             }
@@ -3287,9 +3355,9 @@
                         res = dir_read(&sdj);
                         if (res == FR_OK        /* Not empty dir */
 #if _FS_RPATH
-                        || dclst == dj.fs->cdir /* Current dir */
+                                || dclst == dj.fs->cdir /* Current dir */
 #endif
-                        ) res = FR_DENIED;
+                           ) res = FR_DENIED;
                         if (res == FR_NO_FILE) res = FR_OK; /* Empty */
                     }
                 }
@@ -3351,7 +3419,8 @@
                 ST_DWORD(dir+DIR_WrtTime, tim);
                 st_clust(dir, dcl);
                 mem_cpy(dir+SZ_DIR, dir, SZ_DIR);   /* Create ".." entry */
-                dir[33] = '.'; pcl = dj.sclust;
+                dir[33] = '.';
+                pcl = dj.sclust;
                 if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
                     pcl = 0;
                 st_clust(dir+SZ_DIR, pcl);
@@ -3502,7 +3571,7 @@
                 res = follow_path(&djn, path_new);
                 if (res == FR_OK) res = FR_EXIST;       /* The new object name is already existing */
                 if (res == FR_NO_FILE) {                /* Is it a valid path and no name collision? */
-/* Start critical section that an interruption or error can cause cross-link */
+                    /* Start critical section that an interruption or error can cause cross-link */
                     res = dir_register(&djn);           /* Register the new entry */
                     if (res == FR_OK) {
                         dir = djn.dir;                  /* Copy object information except for name */
@@ -3529,7 +3598,7 @@
                                 res = sync(djo.fs);
                         }
                     }
-/* End critical section */
+                    /* End critical section */
                 }
             }
         }
@@ -3578,12 +3647,12 @@
     if (btr > remain) btr = (UINT)remain;           /* Truncate btr by remaining bytes */
 
     for ( ;  btr && (*func)(0, 0);                  /* Repeat until all data transferred or stream becomes busy */
-        fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
+            fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {
         csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
         if ((fp->fptr % SS(fp->fs)) == 0) {         /* On the sector boundary? */
             if (!csect) {                           /* On the cluster boundary? */
                 clst = (fp->fptr == 0) ?            /* On the top of the file? */
-                    fp->sclust : get_fat(fp->fs, fp->clust);
+                       fp->sclust : get_fat(fp->fs, fp->clust);
                 if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                 fp->clust = clst;                   /* Update current cluster */
@@ -3711,13 +3780,18 @@
     /* Determine number of clusters and final check of validity of the FAT sub-type */
     n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
     if (   (fmt == FS_FAT16 && n_clst < MIN_FAT16)
-        || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
+            || (fmt == FS_FAT32 && n_clst < MIN_FAT32))
         return FR_MKFS_ABORTED;
 
     switch (fmt) {  /* Determine system ID for partition table */
-    case FS_FAT12:  sys = 0x01; break;
-    case FS_FAT16:  sys = (n_vol < 0x10000) ? 0x04 : 0x06; break;
-    default:        sys = 0x0C;
+        case FS_FAT12:
+            sys = 0x01;
+            break;
+        case FS_FAT16:
+            sys = (n_vol < 0x10000) ? 0x04 : 0x06;
+            break;
+        default:
+            sys = 0x0C;
     }
 
     if (_MULTI_PARTITION && part) {
@@ -3826,7 +3900,8 @@
     {
         DWORD eb[2];
 
-        eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
+        eb[0] = wsect;
+        eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
         disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb);
     }
 #endif
@@ -3877,7 +3952,8 @@
 
     /* Create partition table */
     mem_set(buf, 0, _MAX_SS);
-    p = buf + MBR_Table; b_cyl = 0;
+    p = buf + MBR_Table;
+    b_cyl = 0;
     for (i = 0; i < 4; i++, p += SZ_PTE) {
         p_cyl = (szt[i] <= 100) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;
         if (!p_cyl) continue;
@@ -3885,7 +3961,8 @@
         sz_part = (DWORD)sz_cyl * p_cyl;
         if (i == 0) {   /* Exclude first track of cylinder 0 */
             s_hd = 1;
-            s_part += 63; sz_part -= 63;
+            s_part += 63;
+            sz_part -= 63;
         } else {
             s_hd = 0;
         }
@@ -4067,10 +4144,12 @@
         w = f = 0;
         c = *str++;
         if (c == '0') {             /* Flag: '0' padding */
-            f = 1; c = *str++;
+            f = 1;
+            c = *str++;
         } else {
             if (c == '-') {         /* Flag: left justified */
-                f = 2; c = *str++;
+                f = 2;
+                c = *str++;
             }
         }
         while (IsDigit(c)) {        /* Precision */
@@ -4078,36 +4157,43 @@
             c = *str++;
         }
         if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
-            f |= 4; c = *str++;
+            f |= 4;
+            c = *str++;
         }
         if (!c) break;
         d = c;
         if (IsLower(d)) d -= 0x20;
         switch (d) {                /* Type is... */
-        case 'S' :                  /* String */
-            p = va_arg(arp, TCHAR*);
-            for (j = 0; p[j]; j++) ;
-            chc = 0;
-            if (!(f & 2)) {
+            case 'S' :                  /* String */
+                p = va_arg(arp, TCHAR*);
+                for (j = 0; p[j]; j++) ;
+                chc = 0;
+                if (!(f & 2)) {
+                    while (j++ < w) chc += (cc = f_putc(' ', fil));
+                }
+                chc += (cc = f_puts(p, fil));
                 while (j++ < w) chc += (cc = f_putc(' ', fil));
-            }
-            chc += (cc = f_puts(p, fil));
-            while (j++ < w) chc += (cc = f_putc(' ', fil));
-            if (cc != EOF) cc = chc;
-            continue;
-        case 'C' :                  /* Character */
-            cc = f_putc((TCHAR)va_arg(arp, int), fil); continue;
-        case 'B' :                  /* Binary */
-            r = 2; break;
-        case 'O' :                  /* Octal */
-            r = 8; break;
-        case 'D' :                  /* Signed decimal */
-        case 'U' :                  /* Unsigned decimal */
-            r = 10; break;
-        case 'X' :                  /* Hexdecimal */
-            r = 16; break;
-        default:                    /* Unknown type (pass-through) */
-            cc = f_putc(c, fil); continue;
+                if (cc != EOF) cc = chc;
+                continue;
+            case 'C' :                  /* Character */
+                cc = f_putc((TCHAR)va_arg(arp, int), fil);
+                continue;
+            case 'B' :                  /* Binary */
+                r = 2;
+                break;
+            case 'O' :                  /* Octal */
+                r = 8;
+                break;
+            case 'D' :                  /* Signed decimal */
+            case 'U' :                  /* Unsigned decimal */
+                r = 10;
+                break;
+            case 'X' :                  /* Hexdecimal */
+                r = 16;
+                break;
+            default:                    /* Unknown type (pass-through) */
+                cc = f_putc(c, fil);
+                continue;
         }
 
         /* Get an argument and put it in numeral */
@@ -4118,15 +4204,18 @@
         }
         i = 0;
         do {
-            d = (TCHAR)(v % r); v /= r;
+            d = (TCHAR)(v % r);
+            v /= r;
             if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
             s[i++] = d + '0';
         } while (v && i < sizeof s / sizeof s[0]);
         if (f & 8) s[i++] = '-';
-        j = i; d = (f & 1) ? '0' : ' ';
+        j = i;
+        d = (f & 1) ? '0' : ' ';
         res = 0;
         while (!(f & 2) && j++ < w) res += (cc = f_putc(d, fil));
-        do res += (cc = f_putc(s[--i], fil)); while(i);
+        do res += (cc = f_putc(s[--i], fil));
+        while(i);
         while (j++ < w) res += (cc = f_putc(' ', fil));
         if (cc != EOF) cc = res;
     }
--- a/FATFileSystem.h	Thu Nov 29 10:56:08 2012 +0000
+++ b/FATFileSystem.h	Mon Mar 17 14:09:00 2014 +0000
@@ -29,6 +29,9 @@
 
 using namespace mbed;
 
+/**
+  * FATFileSystem based on ChaN's Fat Filesystem library v0.8 
+  */
 class FATFileSystem : public FileSystemLike {
 public:
 
@@ -38,11 +41,30 @@
     static FATFileSystem * _ffs[_VOLUMES];   // FATFileSystem objects, as parallel to FatFs drives array
     FATFS _fs;                               // Work area (file system object) for logical drive
     int _fsid;
-
+    
+    /**
+      * Opens a file on the filesystem
+      */
     virtual FileHandle *open(const char* name, int flags);
+    
+    /**
+     * Removes a file path
+     */
     virtual int remove(const char *filename);
+
+    /**
+     * Formats a logical drive, FDISK artitioning rule, 512 bytes per cluster
+     */
     virtual int format();
+
+    /**
+      * Opens a directory on the filesystem
+      */
     virtual DirHandle *opendir(const char *name);
+    
+    /**
+     * Creates a directory path
+     */
     virtual int mkdir(const char *name, mode_t mode);
 
     virtual int disk_initialize() { return 0; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MemFileSystem.h	Mon Mar 17 14:09:00 2014 +0000
@@ -0,0 +1,77 @@
+/* mbed Microcontroller Library - MemFileSystem
+ * Copyright (c) 2008, sford
+ */
+
+
+#ifndef MBED_MEMFILESYSTEM_H
+#define MBED_MEMFILESYSTEM_H
+
+#include "FATFileSystem.h"
+
+namespace mbed
+{
+
+    class MemFileSystem : public FATFileSystem
+    {
+    public:
+    
+        // 2000 sectors, each 512 bytes (malloced as required)
+        char *sectors[2000];
+    
+        MemFileSystem(const char* name) : FATFileSystem(name) {
+            memset(sectors, 0, sizeof(sectors));
+        }
+    
+        virtual ~MemFileSystem() {
+            for(int i = 0; i < 2000; i++) {
+                if(sectors[i]) {
+                    free(sectors[i]);
+                }
+            }
+        }
+    
+        // read a sector in to the buffer, return 0 if ok
+        virtual int disk_read(char *buffer, int sector) {
+            if(sectors[sector] == 0) {
+                // nothing allocated means sector is empty
+                memset(buffer, 0, 512);
+            } else {
+                memcpy(buffer, sectors[sector], 512);
+            }
+            return 0;
+        }
+    
+        // write a sector from the buffer, return 0 if ok
+        virtual int disk_write(const char *buffer, int sector) {
+            // if buffer is zero deallocate sector
+            char zero[512];
+            memset(zero, 0, 512);
+            if(memcmp(zero, buffer, 512)==0) {
+                if(sectors[sector] != 0) {
+                    free(sectors[sector]);
+                    sectors[sector] = 0;
+                }
+                return 0;
+            }
+            // else allocate a sector if needed, and write
+            if(sectors[sector] == 0) {
+                char *sec = (char*)malloc(512);
+                if(sec==0) {
+                    return 1; // out of memory
+                }
+                sectors[sector] = sec;
+            }
+            memcpy(sectors[sector], buffer, 512);
+            return 0;
+        }
+    
+        // return the number of sectors
+        virtual int disk_sectors() {
+            return sizeof(sectors)/sizeof(sectors[0]);
+        }
+    
+    };
+
+}
+
+#endif
\ No newline at end of file