luat_fs_fatfs.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. #ifdef LUAT_USE_FS_VFS
  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. LLOGE("not support yet : mkfs");
  139. return -1;
  140. }
  141. int luat_vfs_fatfs_mount(void** userdata, luat_fs_conf_t *conf) {
  142. *userdata = (void*)conf->busname;
  143. return 0;
  144. }
  145. int luat_vfs_fatfs_umount(void* userdata, luat_fs_conf_t *conf) {
  146. //LLOGE("not support yet : umount");
  147. return 0;
  148. }
  149. int luat_vfs_fatfs_mkdir(void* userdata, char const* _DirName) {
  150. FRESULT ret = f_mkdir(_DirName);
  151. if (FR_OK == ret)
  152. return 0;
  153. LLOGD("mkdir ret %d", ret);
  154. return -1;
  155. }
  156. int luat_vfs_fatfs_rmdir(void* userdata, char const* _DirName) {
  157. FRESULT ret = f_rmdir(_DirName);
  158. if (FR_OK == ret)
  159. return 0;
  160. LLOGD("rmdir ret %d", ret);
  161. return -1;
  162. }
  163. int luat_vfs_fatfs_lsdir(void* userdata, char const* _DirName, luat_fs_dirent_t* ents, size_t offset, size_t len) {
  164. DIR dir = {0};
  165. FRESULT res = 0;
  166. FILINFO fno = {0};
  167. size_t i = 0;
  168. size_t count = 0;
  169. res = f_opendir(&dir, _DirName);
  170. if (res != FR_OK) {
  171. LLOGD("opendir %s %d", _DirName, res);
  172. return 0;
  173. }
  174. for (i = 0; i < offset; i++)
  175. {
  176. res = f_readdir(&dir, &fno);
  177. if (res != FR_OK || fno.fname[0] == 0) {
  178. return 0; // 读取失败或者是读完了
  179. };
  180. }
  181. for (i = 0; i < len; i++)
  182. {
  183. res = f_readdir(&dir, &fno);
  184. if (res != FR_OK || fno.fname[0] == 0) {
  185. break;
  186. };
  187. count ++;
  188. if (fno.fattrib & AM_DIR) {
  189. ents[i].d_type = 2;
  190. }
  191. else {
  192. ents[i].d_type = 1;
  193. }
  194. if (strlen(fno.fname) < 255)
  195. memcpy(&ents[i].d_name, fno.fname, strlen(fno.fname) + 1);
  196. else {
  197. memcpy(ents[i].d_name, fno.fname, 254);
  198. ents[i].d_name[254] = 0;
  199. }
  200. }
  201. return count;
  202. }
  203. int luat_vfs_fatfs_info(void* userdata, const char* path, luat_fs_info_t *conf) {
  204. // DWORD fre_clust = 0;
  205. // DWORD fre_sect = 0
  206. // DWORD tot_sect = 0;
  207. FATFS *fs = (FATFS*)userdata;
  208. // tot_sect = (fs->n_fatent - 2) * fs->csize;
  209. // fre_sect = (fs->free_clst) * fs->csize;
  210. memcpy(conf->filesystem, "fatfs", strlen("fatfs")+1);
  211. conf->type = 0;
  212. conf->total_block = (fs->n_fatent - 2);
  213. conf->block_used = fs->free_clst;
  214. conf->block_size = fs->csize;
  215. return 0;
  216. }
  217. #define T(name) .name = luat_vfs_fatfs_##name
  218. const struct luat_vfs_filesystem vfs_fs_fatfs = {
  219. .name = "fatfs",
  220. .opts = {
  221. T(mkfs),
  222. T(mount),
  223. T(umount),
  224. T(mkdir),
  225. T(rmdir),
  226. T(lsdir),
  227. T(remove),
  228. T(rename),
  229. T(fsize),
  230. T(fexist),
  231. T(info)
  232. },
  233. .fopts = {
  234. T(fopen),
  235. T(getc),
  236. T(fseek),
  237. T(ftell),
  238. T(fclose),
  239. T(feof),
  240. T(ferror),
  241. T(fread),
  242. T(fwrite)
  243. }
  244. };
  245. #endif