From 2251b0267dda85cf8a096031b1cd01154b567040 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Fri, 21 Feb 2014 01:22:44 +0000 Subject: [PATCH] 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). --- libraries/fs/fat/ChaN/ff.cpp | 16 +++++++++++++++- libraries/fs/fat/ChaN/ffconf.h | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libraries/fs/fat/ChaN/ff.cpp b/libraries/fs/fat/ChaN/ff.cpp index b63b2632b4..fe786a747d 100644 --- a/libraries/fs/fat/ChaN/ff.cpp +++ b/libraries/fs/fat/ChaN/ff.cpp @@ -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); } diff --git a/libraries/fs/fat/ChaN/ffconf.h b/libraries/fs/fat/ChaN/ffconf.h index cc94eaac64..959f984689 100644 --- a/libraries/fs/fat/ChaN/ffconf.h +++ b/libraries/fs/fat/ChaN/ffconf.h @@ -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 */