app3.c 3.7 KB

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