luat_fs_fatfs.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #include "luat_base.h"
  2. #include "luat_fs.h"
  3. #include "luat_malloc.h"
  4. #define LUAT_LOG_TAG "fatfs"
  5. #include "luat_log.h"
  6. #if defined(LUAT_USE_FS_VFS) && defined(LUAT_USE_FATFS)
  7. #include "ff.h"
  8. #include "diskio.h"
  9. FILE* luat_vfs_fatfs_fopen(void* userdata, const char *filename, const char *mode) {
  10. //LLOGD("f_open %s %s", filename, mode);
  11. //FATFS *fs = (FATFS*)userdata;
  12. FIL* fp = luat_heap_malloc(sizeof(FIL));
  13. int flag = 0;
  14. for (size_t i = 0; i < strlen(mode); i++)
  15. {
  16. char m = *(mode + i);
  17. switch (m)
  18. {
  19. case 'r':
  20. flag |= FA_READ;
  21. break;
  22. case 'w':
  23. flag |= FA_WRITE | FA_CREATE_ALWAYS;
  24. break;
  25. case 'a':
  26. flag |= FA_OPEN_APPEND | FA_WRITE;
  27. break;
  28. case '+':
  29. flag |= FA_OPEN_APPEND;
  30. break;
  31. default:
  32. break;
  33. }
  34. }
  35. FRESULT ret = f_open(fp, filename, flag);
  36. if (ret != FR_OK) {
  37. LLOGD("f_open %s %d", filename, ret);
  38. luat_heap_free(fp);
  39. return 0;
  40. }
  41. return (FILE*)fp;
  42. }
  43. int luat_vfs_fatfs_getc(void* userdata, FILE* stream) {
  44. //FATFS *fs = (FATFS*)userdata;
  45. FIL* fp = (FIL*)stream;
  46. char buff = 0;
  47. UINT result = 0;
  48. FRESULT ret = f_read(fp, (void*)&buff, 1, &result);
  49. if (ret == FR_OK && result == 1) {
  50. return buff;
  51. }
  52. return -1;
  53. }
  54. int luat_vfs_fatfs_fseek(void* userdata, FILE* stream, long int offset, int origin) {
  55. //FATFS *fs = (FATFS*)userdata;
  56. FIL* fp = (FIL*)stream;
  57. int npos = f_tell(fp);
  58. if (origin == SEEK_SET) {
  59. npos = offset;
  60. } else if (origin == SEEK_CUR) {
  61. npos += offset;
  62. } else if (origin == SEEK_END) {
  63. npos = f_size(fp);
  64. }
  65. FRESULT ret = f_lseek(fp, npos);
  66. if (ret == FR_OK) {
  67. return 0;
  68. }
  69. return -1;
  70. }
  71. int luat_vfs_fatfs_ftell(void* userdata, FILE* stream) {
  72. //FATFS *fs = (FATFS*)userdata;
  73. FIL* fp = (FIL*)stream;
  74. return f_tell(fp);
  75. }
  76. int luat_vfs_fatfs_fclose(void* userdata, FILE* stream) {
  77. //FATFS *fs = (FATFS*)userdata;
  78. FIL* fp = (FIL*)stream;
  79. if (fp != NULL) {
  80. f_close(fp);
  81. luat_heap_free(fp);
  82. }
  83. return 0;
  84. }
  85. int luat_vfs_fatfs_feof(void* userdata, FILE* stream) {
  86. //FATFS *fs = (FATFS*)userdata;
  87. FIL* fp = (FIL*)stream;
  88. return f_eof(fp);
  89. }
  90. int luat_vfs_fatfs_ferror(void* userdata, FILE *stream) {
  91. //FATFS *fs = (FATFS*)userdata;
  92. FIL* fp = (FIL*)stream;
  93. return f_error(fp);
  94. }
  95. size_t luat_vfs_fatfs_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
  96. //FATFS *fs = (FATFS*)userdata;
  97. FIL* fp = (FIL*)stream;
  98. UINT result = 0;
  99. FRESULT ret = f_read(fp, ptr, size*nmemb, &result);
  100. if (ret == FR_OK) {
  101. return result;
  102. }
  103. return 0;
  104. }
  105. size_t luat_vfs_fatfs_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
  106. //FATFS *fs = (FATFS*)userdata;
  107. FIL* fp = (FIL*)stream;
  108. UINT result = 0;
  109. FRESULT ret = f_write(fp, ptr, size*nmemb, &result);
  110. if (ret == FR_OK) {
  111. return result;
  112. }
  113. return 0;
  114. }
  115. int luat_vfs_fatfs_remove(void* userdata, const char *filename) {
  116. return f_unlink(filename);
  117. }
  118. int luat_vfs_fatfs_rename(void* userdata, const char *old_filename, const char *new_filename) {
  119. return f_rename(old_filename + (old_filename[0] == '/' ? 1 : 0), new_filename + (new_filename[0] == '/' ? 1 : 0));
  120. }
  121. int luat_vfs_fatfs_fexist(void* userdata, const char *filename) {
  122. FILINFO fno = {0};
  123. FRESULT ret = f_stat(filename, &fno);
  124. if (ret == FR_OK) {
  125. return 1;
  126. }
  127. return 0;
  128. }
  129. size_t luat_vfs_fatfs_fsize(void* userdata, const char *filename) {
  130. FILINFO fno = {0};
  131. FRESULT ret = f_stat(filename, &fno);
  132. if (ret == FR_OK) {
  133. return fno.fsize;
  134. }
  135. return 0;
  136. }
  137. int luat_vfs_fatfs_mkfs(void* userdata, luat_fs_conf_t *conf) {
  138. (void)userdata;
  139. (void)conf;
  140. MKFS_PARM parm = {
  141. .fmt = FM_ANY, // 暂时应付一下ramdisk
  142. .au_size = 0,
  143. .align = 0,
  144. .n_fat = 0,
  145. .n_root = 0,
  146. };
  147. BYTE work[FF_MAX_SS] = {0};
  148. int re = f_mkfs("/", &parm, work, FF_MAX_SS);
  149. LLOGD("format ret %d", re);
  150. return re;
  151. }
  152. int luat_vfs_fatfs_mount(void** userdata, luat_fs_conf_t *conf) {
  153. *userdata = (void*)conf->busname;
  154. return 0;
  155. }
  156. int luat_vfs_fatfs_umount(void* userdata, luat_fs_conf_t *conf) {
  157. //LLOGE("not support yet : umount");
  158. return 0;
  159. }
  160. int luat_vfs_fatfs_mkdir(void* userdata, char const* _DirName) {
  161. FRESULT ret = f_mkdir(_DirName);
  162. if (FR_OK == ret)
  163. return 0;
  164. LLOGD("mkdir ret %d", ret);
  165. return -1;
  166. }
  167. int luat_vfs_fatfs_rmdir(void* userdata, char const* _DirName) {
  168. FRESULT ret = f_rmdir(_DirName);
  169. if (FR_OK == ret)
  170. return 0;
  171. LLOGD("rmdir ret %d", ret);
  172. return -1;
  173. }
  174. int luat_vfs_fatfs_lsdir(void* userdata, char const* _DirName, luat_fs_dirent_t* ents, size_t offset, size_t len) {
  175. DIR dir = {0};
  176. FRESULT res = 0;
  177. FILINFO fno = {0};
  178. size_t i = 0;
  179. size_t count = 0;
  180. res = f_opendir(&dir, _DirName);
  181. if (res != FR_OK) {
  182. LLOGD("opendir %s %d", _DirName, res);
  183. return 0;
  184. }
  185. for (i = 0; i < offset; i++)
  186. {
  187. res = f_readdir(&dir, &fno);
  188. if (res != FR_OK || fno.fname[0] == 0) {
  189. return 0; // 读取失败或者是读完了
  190. };
  191. }
  192. for (i = 0; i < len; i++)
  193. {
  194. res = f_readdir(&dir, &fno);
  195. if (res != FR_OK || fno.fname[0] == 0) {
  196. break;
  197. };
  198. count ++;
  199. if (fno.fattrib & AM_DIR) {
  200. ents[i].d_type = 1;
  201. }
  202. else {
  203. ents[i].d_type = 0;
  204. }
  205. if (strlen(fno.fname) < 255)
  206. memcpy(&ents[i].d_name, fno.fname, strlen(fno.fname) + 1);
  207. else {
  208. memcpy(ents[i].d_name, fno.fname, 254);
  209. ents[i].d_name[254] = 0;
  210. }
  211. }
  212. return count;
  213. }
  214. int luat_vfs_fatfs_info(void* userdata, const char* path, luat_fs_info_t *conf) {
  215. // DWORD fre_clust = 0;
  216. // DWORD fre_sect = 0
  217. // DWORD tot_sect = 0;
  218. FATFS *fs = (FATFS*)userdata;
  219. // tot_sect = (fs->n_fatent - 2) * fs->csize;
  220. // fre_sect = (fs->free_clst) * fs->csize;
  221. memcpy(conf->filesystem, "fatfs", strlen("fatfs")+1);
  222. conf->type = 0;
  223. conf->total_block = (fs->n_fatent - 2);
  224. conf->block_used = fs->free_clst;
  225. conf->block_size = fs->csize;
  226. return 0;
  227. }
  228. #define T(name) .name = luat_vfs_fatfs_##name
  229. const struct luat_vfs_filesystem vfs_fs_fatfs = {
  230. .name = "fatfs",
  231. .opts = {
  232. T(mkfs),
  233. T(mount),
  234. T(umount),
  235. T(mkdir),
  236. T(rmdir),
  237. T(lsdir),
  238. T(remove),
  239. T(rename),
  240. T(fsize),
  241. T(fexist),
  242. T(info)
  243. },
  244. .fopts = {
  245. T(fopen),
  246. T(getc),
  247. T(fseek),
  248. T(ftell),
  249. T(fclose),
  250. T(feof),
  251. T(ferror),
  252. T(fread),
  253. T(fwrite)
  254. }
  255. };
  256. #endif