]>
Commit | Line | Data |
---|---|---|
53668523 L |
1 | /*----------------------------------------------------------------------/\r |
2 | / Allocate a contiguous area to the file\r | |
3 | /-----------------------------------------------------------------------/\r | |
4 | / This function checks if the file is contiguous with desired size.\r | |
5 | / If not, a block of contiguous sectors is allocated to the file.\r | |
6 | / If the file has been opened without FA_WRITE flag, it only checks if\r | |
70702af1 L |
7 | / the file is contiguous and returns the resulut.\r |
8 | /-----------------------------------------------------------------------/\r | |
9 | / This function can work with FatFs R0.09 - R0.11a.\r | |
10 | / It is incompatible with R0.12+. Use f_expand function instead.\r | |
11 | /----------------------------------------------------------------------*/\r | |
53668523 L |
12 | \r |
13 | /* Declarations of FatFs internal functions accessible from applications.\r | |
14 | / This is intended to be used for disk checking/fixing or dirty hacks :-) */\r | |
15 | DWORD clust2sect (FATFS* fs, DWORD clst);\r | |
16 | DWORD get_fat (FATFS* fs, DWORD clst);\r | |
17 | FRESULT put_fat (FATFS* fs, DWORD clst, DWORD val);\r | |
18 | \r | |
19 | \r | |
20 | DWORD allocate_contiguous_clusters ( /* Returns the first sector in LBA (0:error or not contiguous) */\r | |
21 | FIL* fp, /* Pointer to the open file object */\r | |
22 | DWORD len /* Number of bytes to allocate */\r | |
23 | )\r | |
24 | {\r | |
25 | DWORD csz, tcl, ncl, ccl, cl;\r | |
26 | \r | |
27 | \r | |
28 | if (f_lseek(fp, 0) || !len) /* Check if the given parameters are valid */\r | |
29 | return 0;\r | |
30 | csz = 512UL * fp->fs->csize; /* Cluster size in unit of byte (assuming 512 bytes/sector) */\r | |
31 | tcl = (len + csz - 1) / csz; /* Total number of clusters required */\r | |
32 | len = tcl * csz; /* Round-up file size to the cluster boundary */\r | |
33 | \r | |
34 | /* Check if the existing cluster chain is contiguous */\r | |
35 | if (len == fp->fsize) {\r | |
36 | ncl = 0; ccl = fp->sclust;\r | |
37 | do {\r | |
38 | cl = get_fat(fp->fs, ccl); /* Get the cluster status */\r | |
39 | if (cl + 1 < 3) return 0; /* Hard error? */\r | |
70702af1 | 40 | if (cl != ccl + 1 && cl < fp->fs->n_fatent) break; /* Not contiguous? */\r |
53668523 L |
41 | ccl = cl;\r |
42 | } while (++ncl < tcl);\r | |
43 | if (ncl == tcl) /* Is the file contiguous? */\r | |
70702af1 | 44 | return clust2sect(fp->fs, fp->sclust); /* File is contiguous. Return the start sector */\r |
53668523 | 45 | }\r |
70702af1 L |
46 | \r |
47 | /* File is not contiguous */\r | |
53668523 | 48 | #if _FS_READONLY\r |
70702af1 | 49 | return 0; /* Exit if in read-only cfg. */\r |
53668523 | 50 | #else\r |
70702af1 L |
51 | if (!(fp->flag & FA_WRITE)) return 0; /* Exit if the file object is for read-only */\r |
52 | \r | |
53 | if (f_truncate(fp)) return 0; /* Remove the non-contiguous chain */\r | |
53668523 L |
54 | \r |
55 | /* Find a free contiguous area */\r | |
56 | ccl = cl = 2; ncl = 0;\r | |
57 | do {\r | |
58 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */\r | |
59 | if (get_fat(fp->fs, cl)) { /* Encounterd a cluster in use */\r | |
60 | do { /* Skip the block of used clusters */\r | |
61 | cl++;\r | |
62 | if (cl >= fp->fs->n_fatent) return 0; /* No contiguous area is found. */\r | |
63 | } while (get_fat(fp->fs, cl));\r | |
64 | ccl = cl; ncl = 0;\r | |
65 | }\r | |
66 | cl++; ncl++;\r | |
67 | } while (ncl < tcl);\r | |
68 | \r | |
69 | /* Create a contiguous cluster chain */\r | |
70 | fp->fs->last_clust = ccl - 1;\r | |
71 | if (f_lseek(fp, len)) return 0;\r | |
72 | \r | |
73 | return clust2sect(fp->fs, fp->sclust); /* Return file start sector */\r | |
74 | #endif\r | |
75 | }\r | |
76 | \r | |
77 | \r | |
78 | int main (void)\r | |
79 | {\r | |
80 | FRESULT fr;\r | |
81 | DRESULT dr;\r | |
82 | FATFS fs;\r | |
83 | FIL fil;\r | |
84 | DWORD org;\r | |
85 | \r | |
86 | \r | |
70702af1 | 87 | /* Open or create a file to write */\r |
53668523 | 88 | f_mount(&fs, "", 0);\r |
70702af1 | 89 | fr = f_open(&fil, "fastrec.log", FA_READ | FA_WRITE | FA_OPEN_ALWAYS);\r |
53668523 L |
90 | if (fr) return 1;\r |
91 | \r | |
70702af1 | 92 | /* Check if the file is 256MB in size and occupies a contiguous area.\r |
53668523 | 93 | / If not, a contiguous area will be re-allocated to the file. */\r |
70702af1 | 94 | org = allocate_contiguous_clusters(&fil, 0x10000000);\r |
53668523 L |
95 | if (!org) {\r |
96 | printf("Function failed due to any error or insufficient contiguous area.\n");\r | |
97 | f_close(&fil);\r | |
98 | return 1;\r | |
99 | }\r | |
100 | \r | |
289f6a14 | 101 | /* Now you can read/write the file without filesystem layer. */\r |
70702af1 | 102 | ...\r |
53668523 | 103 | dr = disk_write(fil.fs->drv, Buff, org, 1024); /* Write 512KiB from top of the file */\r |
53668523 L |
104 | ...\r |
105 | \r | |
106 | f_close(&fil);\r | |
107 | return 0;\r | |
108 | }\r | |
109 | \r |