Skip to content

Commit

Permalink
libraries/fs: Added logic to transparently sync written file
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
oliviermartin committed Feb 21, 2014
1 parent 1f2da5f commit 2251b02
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
16 changes: 15 additions & 1 deletion libraries/fs/fat/ChaN/ff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down
7 changes: 7 additions & 0 deletions libraries/fs/fat/ChaN/ffconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 2251b02

Please sign in to comment.