mayhem-firmware/firmware/chibios-portapack/ext/fatfs/doc/img/app3.c

109 lines
4.0 KiB
C
Raw Normal View History

2015-07-08 15:39:24 +00:00
/*----------------------------------------------------------------------/
/ 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
2016-04-19 16:51:31 +00:00
/ the file is contiguous and returns the resulut.
/-----------------------------------------------------------------------/
/ This function can work with FatFs R0.09 to R0.11a.
/----------------------------------------------------------------------*/
2015-07-08 15:39:24 +00:00
/* 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? */
2016-04-19 16:51:31 +00:00
if (cl != ccl + 1 && cl < fp->fs->n_fatent) break; /* Not contiguous? */
2015-07-08 15:39:24 +00:00
ccl = cl;
} while (++ncl < tcl);
if (ncl == tcl) /* Is the file contiguous? */
2016-04-19 16:51:31 +00:00
return clust2sect(fp->fs, fp->sclust); /* File is contiguous. Return the start sector */
2015-07-08 15:39:24 +00:00
}
2016-04-19 16:51:31 +00:00
/* File is not contiguous */
2015-07-08 15:39:24 +00:00
#if _FS_READONLY
2016-04-19 16:51:31 +00:00
return 0; /* Exit if in read-only cfg. */
2015-07-08 15:39:24 +00:00
#else
2016-04-19 16:51:31 +00:00
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 */
2015-07-08 15:39:24 +00:00
/* 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;
2016-04-19 16:51:31 +00:00
/* Open or create a file to write */
2015-07-08 15:39:24 +00:00
f_mount(&fs, "", 0);
2016-04-19 16:51:31 +00:00
fr = f_open(&fil, "fastrec.log", FA_READ | FA_WRITE | FA_OPEN_ALWAYS);
2015-07-08 15:39:24 +00:00
if (fr) return 1;
2016-04-19 16:51:31 +00:00
/* Check if the file is 256MB in size and occupies a contiguous area.
2015-07-08 15:39:24 +00:00
/ If not, a contiguous area will be re-allocated to the file. */
2016-04-19 16:51:31 +00:00
org = allocate_contiguous_clusters(&fil, 0x10000000);
2015-07-08 15:39:24 +00:00
if (!org) {
printf("Function failed due to any error or insufficient contiguous area.\n");
f_close(&fil);
return 1;
}
2016-04-19 16:51:31 +00:00
/* Now you can read/write the file without file system layer. */
...
2015-07-08 15:39:24 +00:00
dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */
...
f_close(&fil);
return 0;
}