Skip to content

Commit 2251b02

Browse files
committed
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).
1 parent 1f2da5f commit 2251b02

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

libraries/fs/fat/ChaN/ff.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2526,7 +2526,7 @@ FRESULT f_write (
25262526
UINT wcnt, cc;
25272527
const BYTE *wbuff = (const BYTE *)buff;
25282528
BYTE csect;
2529-
2529+
bool need_sync = false;
25302530

25312531
*bw = 0; /* Clear write byte counter */
25322532

@@ -2559,6 +2559,13 @@ FRESULT f_write (
25592559
if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
25602560
if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
25612561
fp->clust = clst; /* Update current cluster */
2562+
2563+
#ifdef FLUSH_ON_NEW_CLUSTER
2564+
// We do not need to flush for the first cluster
2565+
if (fp->fptr != 0) {
2566+
need_sync = true;
2567+
}
2568+
#endif
25622569
}
25632570
#if _FS_TINY
25642571
if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */
@@ -2591,6 +2598,9 @@ FRESULT f_write (
25912598
}
25922599
#endif
25932600
wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
2601+
#ifdef FLUSH_ON_NEW_SECTOR
2602+
need_sync = true;
2603+
#endif
25942604
continue;
25952605
}
25962606
#if _FS_TINY
@@ -2623,6 +2633,10 @@ FRESULT f_write (
26232633
if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */
26242634
fp->flag |= FA__WRITTEN; /* Set file change flag */
26252635

2636+
if (need_sync) {
2637+
f_sync (fp);
2638+
}
2639+
26262640
LEAVE_FF(fp->fs, FR_OK);
26272641
}
26282642

libraries/fs/fat/ChaN/ffconf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,12 @@
187187
/* To enable file lock control feature, set _FS_LOCK to 1 or greater.
188188
The value defines how many files can be opened simultaneously. */
189189

190+
#define FLUSH_ON_NEW_CLUSTER 0 /* Sync the file on every new cluster */
191+
#define FLUSH_ON_NEW_SECTOR 1 /* Sync the file on every new sector */
192+
/* Only one of these two defines needs to be set to 1. If both are set to 0
193+
the file is only sync when closed.
194+
Clusters are group of sectors (eg: 8 sectors). Flushing on new cluster means
195+
it would be less often than flushing on new sector. Sectors are generally
196+
512 Bytes long. */
190197

191198
#endif /* _FFCONFIG */

0 commit comments

Comments
 (0)