app3.c 3.9 KB

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