aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/fatfs-0.13/documents/res/app3.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/fatfs-0.13/documents/res/app3.c')
-rw-r--r--3rdparty/fatfs-0.13/documents/res/app3.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/3rdparty/fatfs-0.13/documents/res/app3.c b/3rdparty/fatfs-0.13/documents/res/app3.c
new file mode 100644
index 00000000..7f9b5088
--- /dev/null
+++ b/3rdparty/fatfs-0.13/documents/res/app3.c
@@ -0,0 +1,109 @@
+/*----------------------------------------------------------------------/
+/ Allocate a contiguous area to the file
+/-----------------------------------------------------------------------/
+/ This function checks if the file is contiguous with desired size.
+/ If not, a block of contiguous sectors is allocated to the file.
+/ If the file has been opened without FA_WRITE flag, it only checks if
+/ the file is contiguous and returns the resulut.
+/-----------------------------------------------------------------------/
+/ This function can work with FatFs R0.09 - R0.11a.
+/ It is incompatible with R0.12+. Use f_expand function instead.
+/----------------------------------------------------------------------*/
+
+/* Declarations of FatFs internal functions accessible from applications.
+/ This is intended to be used for disk checking/fixing or dirty hacks :-) */
+DWORD clust2sect (FATFS* fs, DWORD clst);
+DWORD get_fat (FATFS* fs, DWORD clst);
+FRESULT put_fat (FATFS* fs, DWORD clst, DWORD val);
+
+
+DWORD allocate_contiguous_clusters ( /* Returns the first sector in LBA (0:error or not contiguous) */
+ FIL* fp, /* Pointer to the open file object */
+ DWORD len /* Number of bytes to allocate */
+)
+{
+ DWORD csz, tcl, ncl, ccl, cl;
+
+
+ if (f_lseek(fp, 0) || !len) /* Check if the given parameters are valid */
+ return 0;
+ csz = 512UL * fp->fs->csize; /* Cluster size in unit of byte (assuming 512 bytes/sector) */
+ tcl = (len + csz - 1) / csz; /* Total number of clusters required */
+ len = tcl * csz; /* Round-up file size to the cluster boundary */
+
+ /* Check if the existing cluster chain is contiguous */
+ if (len == fp->fsize) {
+ ncl = 0; ccl = fp->sclust;
+ do {
+ cl = get_fat(fp->fs, ccl); /* Get the cluster status */
+ if (cl + 1 < 3) return 0; /* Hard error? */
+ if (cl != ccl + 1 && cl < fp->fs->n_fatent) break; /* Not contiguous? */
+ ccl = cl;
+ } while (++ncl < tcl);
+ if (ncl == tcl) /* Is the file contiguous? */
+ return clust2sect(fp->fs, fp->sclust); /* File is contiguous. Return the start sector */
+ }
+
+ /* File is not contiguous */
+#if _FS_READONLY
+ return 0; /* Exit if in read-only cfg. */
+#else
+ if (!(fp->flag & FA_WRITE)) return 0; /* Exit if the file object is for read-only */
+
+ if (f_truncate(fp)) return 0; /* Remove the non-contiguous chain */
+
+ /* Find a free contiguous area */
+ ccl = cl = 2; ncl = 0;
+ do {
+ if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */
+ if (get_fat(fp->fs, cl)) { /* Encounterd a cluster in use */
+ do { /* Skip the block of used clusters */
+ cl++;
+ if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */
+ } while (get_fat(fp->fs, cl));
+ ccl = cl; ncl = 0;
+ }
+ cl++; ncl++;
+ } while (ncl < tcl);
+
+ /* Create a contiguous cluster chain */
+ fp->fs->last_clust = ccl - 1;
+ if (f_lseek(fp, len)) return 0;
+
+ return clust2sect(fp->fs, fp->sclust); /* Return file start sector */
+#endif
+}
+
+
+int main (void)
+{
+ FRESULT fr;
+ DRESULT dr;
+ FATFS fs;
+ FIL fil;
+ DWORD org;
+
+
+ /* Open or create a file to write */
+ f_mount(&fs, "", 0);
+ fr = f_open(&fil, "fastrec.log", FA_READ | FA_WRITE | FA_OPEN_ALWAYS);
+ if (fr) return 1;
+
+ /* Check if the file is 256MB in size and occupies a contiguous area.
+ / If not, a contiguous area will be re-allocated to the file. */
+ org = allocate_contiguous_clusters(&fil, 0x10000000);
+ if (!org) {
+ printf("Function failed due to any error or insufficient contiguous area.\n");
+ f_close(&fil);
+ return 1;
+ }
+
+ /* Now you can read/write the file without filesystem layer. */
+ ...
+ dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */
+ ...
+
+ f_close(&fil);
+ return 0;
+}
+