libraries/fs: Added logic to transparently sync written file

fflush() does not do anything in mbed library. The only time the file
was flushed was when it was closed.
For some applications (eg: data logger), files are never closed. It
means when the power went off all the written data were lost.
Actually, they were not lost; they were written into the non-volatile
storage. But the file header was not aware of these new data (its
file information such as file size were not updated).

There is no easy way to retarget fflush() for mbed. So, the workaround
is to fflush (eg: 'sync' in the ChaN terminology) periodically
while writting new data.

The frequency can be changed by the user into ffconf.h.
By default, the updated file will be synced for every new sector (generally
for every 512 bytes). Another available option is to sync for every
new cluster (in my use case, the cluster was 8 sectors long).
pull/184/head
Olivier Martin 2014-02-21 01:22:44 +00:00 committed by Olivier Martin
parent 1f2da5f604
commit 2251b0267d
2 changed files with 22 additions and 1 deletions

View File

@ -2526,7 +2526,7 @@ FRESULT f_write (
UINT wcnt, cc;
const BYTE *wbuff = (const BYTE *)buff;
BYTE csect;
bool need_sync = false;
*bw = 0; /* Clear write byte counter */
@ -2559,6 +2559,13 @@ FRESULT f_write (
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 */
@ -2591,6 +2598,9 @@ FRESULT f_write (
}
#endif
wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
#ifdef FLUSH_ON_NEW_SECTOR
need_sync = true;
#endif
continue;
}
#if _FS_TINY
@ -2623,6 +2633,10 @@ FRESULT f_write (
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);
}

View File

@ -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 */