...
Fork of FATFileSystem by
Revision 4:3ff2606d5713, committed 2014-08-28
- Comitter:
- mbed_official
- Date:
- Thu Aug 28 13:15:31 2014 +0100
- Parent:
- 3:e960e2b81a3c
- Commit message:
- Synchronized with git revision fee50a80ffdc8f9d9ee97be545ff36b5a986f041
Full URL: https://github.com/mbedmicro/mbed/commit/fee50a80ffdc8f9d9ee97be545ff36b5a986f041/
Changed in this revision
diff -r e960e2b81a3c -r 3ff2606d5713 ChaN/diskio.cpp --- a/ChaN/diskio.cpp Mon Mar 17 14:09:00 2014 +0000 +++ b/ChaN/diskio.cpp Thu Aug 28 13:15:31 2014 +0100 @@ -14,7 +14,7 @@ DSTATUS disk_initialize ( BYTE drv /* Physical drive nmuber (0..) */ -) +) { debug_if(FFS_DBG, "disk_initialize on drv [%d]\n", drv); return (DSTATUS)FATFileSystem::_ffs[drv]->disk_initialize(); @@ -22,7 +22,7 @@ DSTATUS disk_status ( BYTE drv /* Physical drive nmuber (0..) */ -) +) { debug_if(FFS_DBG, "disk_status on drv [%d]\n", drv); return (DSTATUS)FATFileSystem::_ffs[drv]->disk_status(); @@ -36,15 +36,10 @@ ) { debug_if(FFS_DBG, "disk_read(sector %d, count %d) on drv [%d]\n", sector, count, drv); - for(DWORD s=sector; s<sector+count; s++) { - debug_if(FFS_DBG, " disk_read(sector %d)\n", s); - int res = FATFileSystem::_ffs[drv]->disk_read((uint8_t*)buff, s); - if(res) { - return RES_PARERR; - } - buff += 512; - } - return RES_OK; + if (FATFileSystem::_ffs[drv]->disk_read((uint8_t*)buff, sector, count)) + return RES_PARERR; + else + return RES_OK; } #if _READONLY == 0 @@ -56,15 +51,10 @@ ) { debug_if(FFS_DBG, "disk_write(sector %d, count %d) on drv [%d]\n", sector, count, drv); - for(DWORD s = sector; s < sector + count; s++) { - debug_if(FFS_DBG, " disk_write(sector %d)\n", s); - int res = FATFileSystem::_ffs[drv]->disk_write((uint8_t*)buff, s); - if(res) { - return RES_PARERR; - } - buff += 512; - } - return RES_OK; + if (FATFileSystem::_ffs[drv]->disk_write((uint8_t*)buff, sector, count)) + return RES_PARERR; + else + return RES_OK; } #endif /* _READONLY */
diff -r e960e2b81a3c -r 3ff2606d5713 ChaN/ff.cpp --- a/ChaN/ff.cpp Mon Mar 17 14:09:00 2014 +0000 +++ b/ChaN/ff.cpp Thu Aug 28 13:15:31 2014 +0100 @@ -527,16 +527,14 @@ /* 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 @@ -546,8 +544,7 @@ /* 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--) @@ -556,8 +553,7 @@ /* 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; @@ -567,8 +563,7 @@ /* 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; } @@ -596,10 +591,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); } } @@ -624,8 +619,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++; } @@ -659,8 +654,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. */ @@ -836,25 +831,23 @@ 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 */ @@ -884,38 +877,37 @@ } 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; } @@ -951,14 +943,8 @@ 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; /* Internal error? */ - break; - } - if (nxt == 0xFFFFFFFF) { - res = FR_DISK_ERR; /* Disk error? */ - break; - } + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ if (res != FR_OK) break; if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */ @@ -1003,7 +989,8 @@ 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 */ @@ -1064,8 +1051,7 @@ 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 */ } @@ -1099,7 +1085,8 @@ 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 */ @@ -1145,7 +1132,8 @@ 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; @@ -1240,8 +1228,7 @@ 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 */ @@ -1273,8 +1260,7 @@ 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 */ @@ -1346,8 +1332,7 @@ 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) */ @@ -1388,8 +1373,7 @@ 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 @@ -1423,10 +1407,7 @@ 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; /* Reached to end of table */ - break; - } + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ #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 */ @@ -1436,8 +1417,7 @@ 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 */ @@ -1445,8 +1425,7 @@ } } 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? */ } } @@ -1484,10 +1463,7 @@ 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; /* Reached to end of table */ - break; - } + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ #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 */ @@ -1496,8 +1472,7 @@ 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 */ @@ -1541,16 +1516,14 @@ 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 */ @@ -1558,8 +1531,7 @@ } 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. */ @@ -1714,8 +1686,7 @@ b = (BYTE)p[si++]; /* Get 2nd byte */ if (!IsDBCS2(b)) return FR_INVALID_NAME; /* Reject invalid sequence */ - else - w = (w << 8) + b; /* Create a DBC */ + 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 */ @@ -1728,7 +1699,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) ? '.' : ' '; @@ -1751,28 +1722,22 @@ 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 */ @@ -1787,22 +1752,18 @@ 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; } } } @@ -1834,8 +1795,7 @@ 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 (;;) { @@ -1854,10 +1814,8 @@ 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 */ @@ -1882,8 +1840,7 @@ b |= 2; } else { if (IsLower(c)) { /* ASCII small capital? */ - b |= 1; - c -= 0x20; + b |= 1; c -= 0x20; } } sfn[i++] = c; @@ -1973,17 +1930,11 @@ while ((w = *lfn++) != 0) { /* Get an LFN char */ #if !_LFN_UNICODE w = ff_convert(w, 0); /* Unicode -> OEM conversion */ - if (!w) { - i = 0; /* Could not convert, no LFN */ - break; - } + if (!w) { i = 0; break; } /* Could not convert, no LFN */ 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; /* Buffer overflow, no LFN */ - break; - } + if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */ tp[i++] = (TCHAR)w; } } @@ -2012,8 +1963,7 @@ #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 */ } @@ -2036,8 +1986,7 @@ 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 */ @@ -2048,8 +1997,7 @@ 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); } @@ -2110,8 +2058,7 @@ /* 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 */ @@ -2215,7 +2162,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; @@ -2230,11 +2177,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 @@ -2382,7 +2329,8 @@ #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 { @@ -2407,7 +2355,8 @@ } } } - } 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; @@ -2450,8 +2399,7 @@ #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 */ } } @@ -2490,7 +2438,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? */ @@ -2578,7 +2526,7 @@ UINT wcnt, cc; const BYTE *wbuff = (const BYTE *)buff; BYTE csect; - + bool need_sync = false; *bw = 0; /* Clear write byte counter */ @@ -2591,7 +2539,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? */ @@ -2611,6 +2559,13 @@ if (clst == 1) ABORT(fp->fs, FR_INT_ERR); if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); fp->clust = clst; /* Update current cluster */ + +#ifdef FLUSH_ON_NEW_CLUSTER + // We do not need to flush for the first cluster + if (fp->fptr != 0) { + need_sync = true; + } +#endif } #if _FS_TINY if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */ @@ -2643,6 +2598,9 @@ } #endif wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ +#ifdef FLUSH_ON_NEW_SECTOR + need_sync = true; +#endif continue; } #if _FS_TINY @@ -2653,8 +2611,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; @@ -2675,6 +2633,10 @@ if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ fp->flag |= FA__WRITTEN; /* Set file change flag */ + if (need_sync) { + f_sync (fp); + } + LEAVE_FF(fp->fs, FR_OK); } @@ -2869,8 +2831,7 @@ 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] = '/'; @@ -2922,25 +2883,20 @@ 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 */ } @@ -2978,22 +2934,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; @@ -3015,8 +2971,7 @@ 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 @@ -3217,21 +3172,14 @@ 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++); @@ -3241,12 +3189,10 @@ } 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); } @@ -3355,9 +3301,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 */ } } @@ -3419,8 +3365,7 @@ 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); @@ -3571,7 +3516,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 */ @@ -3598,7 +3543,7 @@ res = sync(djo.fs); } } - /* End critical section */ +/* End critical section */ } } } @@ -3647,12 +3592,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 */ @@ -3780,18 +3725,13 @@ /* 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) { @@ -3900,8 +3840,7 @@ { 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 @@ -3952,8 +3891,7 @@ /* 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; @@ -3961,8 +3899,7 @@ 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; } @@ -4144,12 +4081,10 @@ 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 */ @@ -4157,43 +4092,36 @@ 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)) { - while (j++ < w) chc += (cc = f_putc(' ', fil)); - } - chc += (cc = f_puts(p, fil)); + 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)); - 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; + } + 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; } /* Get an argument and put it in numeral */ @@ -4204,18 +4132,15 @@ } 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; }
diff -r e960e2b81a3c -r 3ff2606d5713 ChaN/ffconf.h --- a/ChaN/ffconf.h Mon Mar 17 14:09:00 2014 +0000 +++ b/ChaN/ffconf.h Thu Aug 28 13:15:31 2014 +0100 @@ -187,5 +187,12 @@ /* To enable file lock control feature, set _FS_LOCK to 1 or greater. The value defines how many files can be opened simultaneously. */ +#define FLUSH_ON_NEW_CLUSTER 0 /* Sync the file on every new cluster */ +#define FLUSH_ON_NEW_SECTOR 1 /* Sync the file on every new sector */ +/* Only one of these two defines needs to be set to 1. If both are set to 0 + the file is only sync when closed. + Clusters are group of sectors (eg: 8 sectors). Flushing on new cluster means + it would be less often than flushing on new sector. Sectors are generally + 512 Bytes long. */ #endif /* _FFCONFIG */
diff -r e960e2b81a3c -r 3ff2606d5713 FATFileHandle.cpp --- a/FATFileHandle.cpp Mon Mar 17 14:09:00 2014 +0000 +++ b/FATFileHandle.cpp Thu Aug 28 13:15:31 2014 +0100 @@ -38,13 +38,13 @@ ssize_t FATFileHandle::write(const void* buffer, size_t length) { UINT n; FRESULT res = f_write(&_fh, buffer, length, &n); - if (res) { + if (res) { debug_if(FFS_DBG, "f_write() failed: %d", res); return -1; } return n; } - + ssize_t FATFileHandle::read(void* buffer, size_t length) { debug_if(FFS_DBG, "read(%d)\n", length); UINT n;
diff -r e960e2b81a3c -r 3ff2606d5713 FATFileSystem.cpp --- a/FATFileSystem.cpp Mon Mar 17 14:09:00 2014 +0000 +++ b/FATFileSystem.cpp Thu Aug 28 13:15:31 2014 +0100 @@ -69,7 +69,7 @@ debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%d]\n", name, _name, _fsid); char n[64]; sprintf(n, "%d:/%s", _fsid, name); - + /* POSIX flags -> FatFS open mode */ BYTE openmode; if (flags & O_RDWR) { @@ -86,10 +86,10 @@ openmode |= FA_OPEN_ALWAYS; } } - + FIL fh; FRESULT res = f_open(&fh, n, openmode); - if (res) { + if (res) { debug_if(FFS_DBG, "f_open('w') failed: %d\n", res); return NULL; } @@ -98,16 +98,25 @@ } return new FATFileHandle(fh); } - + int FATFileSystem::remove(const char *filename) { FRESULT res = f_unlink(filename); - if (res) { + if (res) { debug_if(FFS_DBG, "f_unlink() failed: %d\n", res); return -1; } return 0; } +int FATFileSystem::rename(const char *oldname, const char *newname) { + FRESULT res = f_rename(oldname, newname); + if (res) { + debug_if(FFS_DBG, "f_rename() failed: %d\n", res); + return -1; + } + return 0; +} + int FATFileSystem::format() { FRESULT res = f_mkfs(_fsid, 0, 512); // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster) if (res) { @@ -130,3 +139,15 @@ FRESULT res = f_mkdir(name); return res == 0 ? 0 : -1; } + +int FATFileSystem::mount() { + FRESULT res = f_mount(_fsid, &_fs); + return res == 0 ? 0 : -1; +} + +int FATFileSystem::unmount() { + if (disk_sync()) + return -1; + FRESULT res = f_mount(_fsid, NULL); + return res == 0 ? 0 : -1; +}
diff -r e960e2b81a3c -r 3ff2606d5713 FATFileSystem.h --- a/FATFileSystem.h Mon Mar 17 14:09:00 2014 +0000 +++ b/FATFileSystem.h Thu Aug 28 13:15:31 2014 +0100 @@ -30,8 +30,8 @@ using namespace mbed; /** - * FATFileSystem based on ChaN's Fat Filesystem library v0.8 - */ + * FATFileSystem based on ChaN's Fat Filesystem library v0.8 + */ class FATFileSystem : public FileSystemLike { public: @@ -41,36 +41,51 @@ 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 - */ + * Opens a file on the filesystem + */ virtual FileHandle *open(const char* name, int flags); /** * Removes a file path */ virtual int remove(const char *filename); - + + /** + * Renames a file + */ + virtual int rename(const char *oldname, const char *newname); + /** * Formats a logical drive, FDISK artitioning rule, 512 bytes per cluster */ virtual int format(); - + /** - * Opens a directory on the filesystem - */ + * 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); + + /** + * Mounts the filesystem + */ + virtual int mount(); + + /** + * Unmounts the filesystem + */ + virtual int unmount(); virtual int disk_initialize() { return 0; } virtual int disk_status() { return 0; } - virtual int disk_read(uint8_t * buffer, uint64_t sector) = 0; - virtual int disk_write(const uint8_t * buffer, uint64_t sector) = 0; + virtual int disk_read(uint8_t * buffer, uint64_t sector, uint8_t count) = 0; + virtual int disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count) = 0; virtual int disk_sync() { return 0; } virtual uint64_t disk_sectors() = 0;