mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
1f2da5f604
commit
2251b0267d
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue