luat_lib_fatfs.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. @module fatfs
  3. @summary 读写fatfs格式
  4. @version 1.0
  5. @date 2020.07.03
  6. @demo fatfs
  7. @tag LUAT_USE_FATFS
  8. @usage
  9. -- 通常只使用fatfs.mount挂载tf/sd卡,其他操作走io库就可以了
  10. */
  11. #include "luat_base.h"
  12. #include "luat_spi.h"
  13. #include "luat_sdio.h"
  14. #include "luat_timer.h"
  15. #include "luat_gpio.h"
  16. #include "luat_malloc.h"
  17. #include "luat_fs.h"
  18. #include "ff.h" /* Obtains integer types */
  19. #include "diskio.h" /* Declarations of disk functions */
  20. #define LUAT_LOG_TAG "fatfs"
  21. #include "luat_log.h"
  22. static FATFS *fs = NULL; /* FatFs work area needed for each volume */
  23. extern BYTE FATFS_DEBUG; // debug log, 0 -- disable , 1 -- enable
  24. extern BYTE FATFS_POWER_PIN;
  25. extern uint16_t FATFS_POWER_DELAY;
  26. DRESULT diskio_open_ramdisk(BYTE pdrv, size_t len);
  27. DRESULT diskio_open_spitf(BYTE pdrv, void* userdata);
  28. DRESULT diskio_open_sdio(BYTE pdrv, void* userdata);
  29. #ifdef LUAT_USE_FS_VFS
  30. extern const struct luat_vfs_filesystem vfs_fs_fatfs;
  31. #endif
  32. /*
  33. 挂载fatfs
  34. @api fatfs.mount(mode,mount_point, spiid_or_spidevice, spi_cs, spi_speed, power_pin, power_on_delay, auto_format)
  35. @int fatfs模式,可选fatfs.SPI,fatfs.SDIO,fatfs.RAM,fatfs.USB
  36. @string 虚拟文件系统的挂载点, 默认是 /fatfs
  37. @int 传入spi device指针,或者spi的id,或者sdio的id
  38. @int 片选脚的GPIO 号, spi模式有效,若前一个参数传的是spi device,这个参数就不需要传
  39. @int SPI最高速度,默认10M, 若前2个参数传的是spi device,这个参数就不需要传
  40. @int TF卡电源控制脚,TF卡初始前先拉低复位再拉高,如果没有,或者是内置电源控制方式,这个参数就不需要传
  41. @int TF卡电源复位过程时间,单位ms,默认值是1
  42. @bool 挂载失败是否尝试格式化,默认是true,即自动格式化. 本参数在2023.8.16添加
  43. @return bool 成功返回true, 否则返回nil或者false
  44. @return string 失败的原因
  45. @usage
  46. -- 方法1, 使用SPI模式
  47. local spiId = 2
  48. local result = spi.setup(
  49. spiId,--串口id
  50. 255, -- 不使用默认CS脚
  51. 0,--CPHA
  52. 0,--CPOL
  53. 8,--数据宽度
  54. 400*1000 -- 初始化时使用较低的频率
  55. )
  56. local TF_CS = pin.PB3
  57. gpio.setup(TF_CS, 1)
  58. --fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因
  59. -- 提醒, 若TF/SD模块带电平转换, 通常不支持10M以上的波特率!!
  60. fatfs.mount(fatfs.SPI,"SD", spiId, TF_CS, 24000000)
  61. local data, err = fatfs.getfree("SD")
  62. if data then
  63. log.info("fatfs", "getfree", json.encode(data))
  64. else
  65. log.info("fatfs", "err", err)
  66. end
  67. -- 往下的操作, 使用 io.open("/sd/xxx", "w+") 等io库的API就可以了
  68. */
  69. static int fatfs_mount(lua_State *L)
  70. {
  71. if (FATFS_DEBUG)
  72. LLOGD("fatfs_init>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  73. if (fs == NULL) {
  74. fs = luat_heap_malloc(sizeof(FATFS));
  75. if (fs == NULL) {
  76. lua_pushboolean(L, 0);
  77. LLOGD("out of memory when malloc FATFS");
  78. lua_pushstring(L, "out of memory when malloc FATFS");
  79. return 2;
  80. }
  81. }
  82. // 挂载点
  83. const char *mount_point = luaL_optstring(L, 2, "/fatfs");
  84. int fatfs_mode = luaL_checkinteger(L, 1);
  85. FATFS_POWER_PIN = luaL_optinteger(L, 6, 0xff);
  86. FATFS_POWER_DELAY = luaL_optinteger(L, 7, 1);
  87. if (fatfs_mode == DISK_SPI){
  88. luat_fatfs_spi_t *spit = luat_heap_malloc(sizeof(luat_fatfs_spi_t));
  89. if (spit == NULL) {
  90. lua_pushboolean(L, 0);
  91. LLOGD("out of memory when malloc luat_fatfs_spi_t");
  92. lua_pushstring(L, "out of memory when malloc luat_fatfs_spi_t");
  93. return 2;
  94. }
  95. memset(spit, 0, sizeof(luat_fatfs_spi_t));
  96. if (lua_type(L, 3) == LUA_TUSERDATA){
  97. spit->spi_device = (luat_spi_device_t*)lua_touserdata(L, 3);
  98. spit->fast_speed = luaL_optinteger(L, 4, 10000000);
  99. spit->type = 1;
  100. diskio_open_spitf(0, (void*)spit);
  101. } else {
  102. spit->type = 0;
  103. spit->spi_id = luaL_optinteger(L, 3, 0); // SPI_1
  104. spit->spi_cs = luaL_optinteger(L, 4, 3); // GPIO_3
  105. spit->fast_speed = luaL_optinteger(L, 5, 10000000);
  106. LLOGD("init sdcard at spi=%d cs=%d", spit->spi_id, spit->spi_cs);
  107. diskio_open_spitf(0, (void*)spit);
  108. }
  109. }else if(fatfs_mode == DISK_SDIO){
  110. luat_fatfs_sdio_t *fatfs_sdio = luat_heap_malloc(sizeof(luat_fatfs_sdio_t));
  111. if (fatfs_sdio == NULL) {
  112. lua_pushboolean(L, 0);
  113. LLOGD("out of memory when malloc luat_fatfs_sdio_t");
  114. lua_pushstring(L, "out of memory when malloc luat_fatfs_sdio_t");
  115. return 2;
  116. }
  117. memset(fatfs_sdio, 0, sizeof(luat_fatfs_sdio_t));
  118. fatfs_sdio->id = luaL_optinteger(L, 3, 0); // SDIO_ID
  119. LLOGD("init FatFS at sdio");
  120. diskio_open_sdio(0, (void*)fatfs_sdio);
  121. }else if(fatfs_mode == DISK_RAM){
  122. LLOGD("init ramdisk at FatFS");
  123. diskio_open_ramdisk(0, luaL_optinteger(L, 3, 64*1024));
  124. }else if(fatfs_mode == DISK_USB){
  125. }else{
  126. LLOGD("fatfs_mode error");
  127. lua_pushboolean(L, 0);
  128. lua_pushstring(L, "fatfs_mode error");
  129. return 2;
  130. }
  131. FRESULT re = f_mount(fs, "/", 0);
  132. if (re != FR_OK) {
  133. if (lua_isboolean(L, 8) && lua_toboolean(L, 8) == 0) {
  134. LLOGI("sd/tf mount failed %d but auto-format is disabled", re);
  135. }
  136. else {
  137. LLOGD("mount failed, try auto format");
  138. MKFS_PARM parm = {
  139. .fmt = FM_ANY, // 暂时应付一下ramdisk
  140. .au_size = 0,
  141. .align = 0,
  142. .n_fat = 0,
  143. .n_root = 0,
  144. };
  145. BYTE work[FF_MAX_SS] = {0};
  146. re = f_mkfs("/", &parm, work, FF_MAX_SS);
  147. LLOGD("auto format ret %d", re);
  148. if (re == FR_OK) {
  149. re = f_mount(fs, "/", 0);
  150. LLOGD("remount again %d", re);
  151. }
  152. }
  153. }
  154. lua_pushboolean(L, re == FR_OK);
  155. lua_pushinteger(L, re);
  156. if (re == FR_OK) {
  157. if (FATFS_DEBUG)
  158. LLOGD("[FatFS]fatfs_init success");
  159. #ifdef LUAT_USE_FS_VFS
  160. luat_fs_conf_t conf2 = {
  161. .busname = (char*)fs,
  162. .type = "fatfs",
  163. .filesystem = "fatfs",
  164. .mount_point = mount_point,
  165. };
  166. luat_fs_mount(&conf2);
  167. #endif
  168. }
  169. else {
  170. if (FATFS_DEBUG)
  171. LLOGD("[FatFS]fatfs_init FAIL!! re=%d", re);
  172. }
  173. if (FATFS_DEBUG)
  174. LLOGD("fatfs_init<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
  175. return 2;
  176. }
  177. static int fatfs_unmount(lua_State *L) {
  178. const char *mount_point = luaL_optstring(L, 1, "");
  179. FRESULT re = f_unmount(mount_point);
  180. lua_pushinteger(L, re);
  181. return 1;
  182. }
  183. static int fatfs_mkfs(lua_State *L) {
  184. const char *mount_point = luaL_optstring(L, 1, "");
  185. // BYTE sfd = luaL_optinteger(L, 2, 0);
  186. // DWORD au = luaL_optinteger(L, 3, 0);
  187. BYTE work[FF_MAX_SS] = {0};
  188. if (FATFS_DEBUG)
  189. LLOGI("mkfs GO %d");
  190. MKFS_PARM parm = {
  191. .fmt = FM_ANY, // 暂时应付一下ramdisk
  192. .au_size = 0,
  193. .align = 0,
  194. .n_fat = 0,
  195. .n_root = 0,
  196. };
  197. if (!strcmp("ramdisk", mount_point) || !strcmp("ram", mount_point)) {
  198. parm.fmt = FM_ANY | FM_SFD;
  199. }
  200. FRESULT re = f_mkfs(mount_point, &parm, work, FF_MAX_SS);
  201. lua_pushinteger(L, re);
  202. if (FATFS_DEBUG)
  203. LLOGI("mkfs ret %d", re);
  204. return 1;
  205. }
  206. /**
  207. 获取可用空间信息
  208. @api fatfs.getfree(mount_point)
  209. @string 挂载点, 需要跟fatfs.mount传入的值一致
  210. @return table 若成功会返回table,否则返回nil
  211. @return int 导致失败的底层返回值
  212. @usage
  213. -- table包含的内容有
  214. -- total_sectors 总扇区数量
  215. -- free_sectors 空闲扇区数量
  216. -- total_kb 总字节数,单位kb
  217. -- free_kb 空闲字节数, 单位kb
  218. -- 注意,当前扇区大小固定在512字节
  219. local data, err = fatfs.getfree("SD")
  220. if data then
  221. log.info("fatfs", "getfree", json.encode(data))
  222. else
  223. log.info("fatfs", "err", err)
  224. end
  225. */
  226. static int fatfs_getfree(lua_State *L)
  227. {
  228. DWORD fre_clust, fre_sect, tot_sect;
  229. // 挂载点
  230. const char *mount_point = luaL_optstring(L, 1, "");
  231. FATFS *fs2;
  232. FRESULT re2 = f_getfree(mount_point, &fre_clust, &fs2);
  233. if (re2) {
  234. lua_pushnil(L);
  235. lua_pushinteger(L, re2);
  236. return 2;
  237. }
  238. /* Get total sectors and free sectors */
  239. tot_sect = (fs2->n_fatent - 2) * fs2->csize;
  240. fre_sect = fre_clust * fs2->csize;
  241. lua_newtable(L);
  242. lua_pushstring(L, "total_sectors");
  243. lua_pushinteger(L, tot_sect);
  244. lua_settable(L, -3);
  245. lua_pushstring(L, "free_sectors");
  246. lua_pushinteger(L, fre_sect);
  247. lua_settable(L, -3);
  248. lua_pushstring(L, "total_kb");
  249. lua_pushinteger(L, tot_sect / 2);
  250. lua_settable(L, -3);
  251. lua_pushstring(L, "free_kb");
  252. lua_pushinteger(L, fre_sect / 2);
  253. lua_settable(L, -3);
  254. return 1;
  255. }
  256. // ------------------------------------------------
  257. // ------------------------------------------------
  258. static int fatfs_mkdir(lua_State *L) {
  259. int luaType = lua_type( L, 1);
  260. if(luaType != LUA_TSTRING) {
  261. lua_pushinteger(L, -1);
  262. lua_pushstring(L, "file path must string");
  263. return 2;
  264. }
  265. FRESULT re = f_mkdir(lua_tostring(L, 1));
  266. lua_pushinteger(L, re);
  267. return 1;
  268. }
  269. static int fatfs_lsdir(lua_State *L)
  270. {
  271. //FIL Fil; /* File object needed for each open file */
  272. DIR dir;
  273. FILINFO fileinfo;
  274. int luaType = lua_type( L, 1);
  275. if(luaType != LUA_TSTRING) {
  276. lua_pushinteger(L, -1);
  277. lua_pushstring(L, "dir must string");
  278. return 2;
  279. }
  280. //u8 *buf;
  281. size_t len;
  282. const char *buf = lua_tolstring( L, 1, &len );
  283. char dirname[len+1];
  284. memcpy(dirname, buf, len);
  285. dirname[len] = 0x00;
  286. FRESULT re = f_opendir(&dir, dirname);
  287. if (re != FR_OK) {
  288. lua_pushinteger(L, re);
  289. return 1;
  290. }
  291. lua_pushinteger(L, 0);
  292. lua_newtable(L);
  293. while(f_readdir(&dir, &fileinfo) == FR_OK) {
  294. if(!fileinfo.fname[0]) break;
  295. lua_pushlstring(L, fileinfo.fname, strlen(fileinfo.fname));
  296. lua_newtable(L);
  297. lua_pushstring(L, "size");
  298. lua_pushinteger(L, fileinfo.fsize);
  299. lua_settable(L, -3);
  300. lua_pushstring(L, "date");
  301. lua_pushinteger(L, fileinfo.fdate);
  302. lua_settable(L, -3);
  303. lua_pushstring(L, "time");
  304. lua_pushinteger(L, fileinfo.ftime);
  305. lua_settable(L, -3);
  306. lua_pushstring(L, "attrib");
  307. lua_pushinteger(L, fileinfo.fattrib);
  308. lua_settable(L, -3);
  309. lua_pushstring(L, "isdir");
  310. lua_pushinteger(L, fileinfo.fattrib & AM_DIR);
  311. lua_settable(L, -3);
  312. lua_settable(L, -3);
  313. }
  314. f_closedir(&dir);
  315. //LLOGD("[FatFS] lua_gettop=%d", lua_gettop(L));
  316. return 2;
  317. }
  318. //-------------------------------------------------------------
  319. static int fatfs_stat(lua_State *L) {
  320. int luaType = lua_type(L, 1);
  321. if(luaType != LUA_TSTRING) {
  322. lua_pushinteger(L, -1);
  323. lua_pushstring(L, "file path must string");
  324. return 2;
  325. }
  326. FILINFO fileinfo;
  327. const char *path = lua_tostring(L, 1);
  328. FRESULT re = f_stat(path, &fileinfo);
  329. lua_pushinteger(L, re);
  330. if (re == FR_OK) {
  331. lua_newtable(L);
  332. lua_pushstring(L, "size");
  333. lua_pushinteger(L, fileinfo.fsize);
  334. lua_rawset(L, -3);
  335. lua_pushstring(L, "date");
  336. lua_pushinteger(L, fileinfo.fdate);
  337. lua_rawset(L, -3);
  338. lua_pushstring(L, "time");
  339. lua_pushinteger(L, fileinfo.ftime);
  340. lua_rawset(L, -3);
  341. lua_pushstring(L, "attrib");
  342. lua_pushinteger(L, fileinfo.fattrib);
  343. lua_rawset(L, -3);
  344. lua_pushstring(L, "isdir");
  345. lua_pushinteger(L, fileinfo.fattrib & AM_DIR);
  346. lua_rawset(L, -3);
  347. }
  348. else {
  349. lua_pushnil(L);
  350. }
  351. return 2;
  352. }
  353. /**
  354. * fatfs.open("adc.txt")
  355. * fatfs.open("adc.txt", 2)
  356. */
  357. static int fatfs_open(lua_State *L) {
  358. int luaType = lua_type( L, 1);
  359. if(luaType != LUA_TSTRING) {
  360. lua_pushnil(L);
  361. lua_pushinteger(L, -1);
  362. lua_pushstring(L, "file path must string");
  363. return 3;
  364. }
  365. const char *path = lua_tostring(L, 1);
  366. int flag = luaL_optinteger(L, 2, 1); // 第二个参数
  367. flag |= luaL_optinteger(L, 3, 0); // 第三个参数
  368. flag |= luaL_optinteger(L, 4, 0); // 第四个参数
  369. if (FATFS_DEBUG)
  370. LLOGD("[FatFS]open %s %0X", path, flag);
  371. FIL* fil = (FIL*)lua_newuserdata(L, sizeof(FIL));
  372. FRESULT re = f_open(fil, path, (BYTE)flag);
  373. if (re != FR_OK) {
  374. lua_remove(L, -1);
  375. lua_pushnil(L);
  376. lua_pushinteger(L, re);
  377. return 2;
  378. }
  379. return 1;
  380. }
  381. static int fatfs_close(lua_State *L) {
  382. int luaType = lua_type(L, 1);
  383. if(luaType != LUA_TUSERDATA) {
  384. lua_pushinteger(L, -1);
  385. lua_pushstring(L, "must be FIL*");
  386. return 2;
  387. }
  388. FIL* fil = (FIL*)lua_touserdata(L, 1);
  389. FRESULT re = f_close(fil);
  390. //free(fil);
  391. lua_pushinteger(L, re);
  392. return 1;
  393. }
  394. static int fatfs_seek(lua_State *L) {
  395. int luaType = lua_type( L, 1);
  396. if(luaType != LUA_TUSERDATA) {
  397. lua_pushinteger(L, -1);
  398. lua_pushstring(L, "must be FIL*");
  399. return 2;
  400. }
  401. UINT seek = luaL_optinteger(L, 2, 0);
  402. FRESULT re = f_lseek((FIL*)lua_touserdata(L, 1), seek);
  403. lua_pushinteger(L, re);
  404. return 1;
  405. }
  406. static int fatfs_truncate(lua_State *L) {
  407. int luaType = lua_type( L, 1);
  408. if(luaType != LUA_TUSERDATA) {
  409. lua_pushinteger(L, -1);
  410. lua_pushstring(L, "must be FIL*");
  411. return 2;
  412. }
  413. FRESULT re = f_truncate((FIL*)lua_touserdata(L, 1));
  414. lua_pushinteger(L, re);
  415. return 1;
  416. }
  417. static int fatfs_read(lua_State *L) {
  418. int luaType = lua_type( L, 1);
  419. if(luaType != LUA_TUSERDATA) {
  420. lua_pushinteger(L, -1);
  421. lua_pushstring(L, "must be FIL*");
  422. return 2;
  423. }
  424. UINT limit = luaL_optinteger(L, 2, 512);
  425. BYTE buf[limit];
  426. UINT len;
  427. if (FATFS_DEBUG)
  428. LLOGD("[FatFS]readfile limit=%d", limit);
  429. FRESULT re = f_read((FIL*)lua_touserdata(L, 1), buf, limit, &len);
  430. lua_pushinteger(L, re);
  431. if (re != FR_OK) {
  432. return 1;
  433. }
  434. lua_pushlstring(L, (const char*)buf, len);
  435. return 2;
  436. }
  437. static int fatfs_write(lua_State *L) {
  438. int luaType = lua_type( L, 1);
  439. if(luaType != LUA_TUSERDATA) {
  440. lua_pushinteger(L, -1);
  441. lua_pushstring(L, "must be FIL*");
  442. return 2;
  443. }
  444. FIL* fil = (FIL*)lua_touserdata(L, 1);
  445. luaType = lua_type( L, 2 );
  446. size_t len;
  447. char* buf;
  448. FRESULT re = FR_OK;
  449. if(luaType == LUA_TSTRING )
  450. {
  451. buf = (char*)lua_tolstring( L, 2, &len );
  452. re = f_write(fil, buf, len, &len);
  453. }
  454. else if(luaType == LUA_TLIGHTUSERDATA)
  455. {
  456. buf = lua_touserdata(L, 2);
  457. len = lua_tointeger( L, 3);
  458. re = f_write(fil, buf, len, &len);
  459. }
  460. if (FATFS_DEBUG)
  461. LLOGD("[FatFS]write re=%d len=%d", re, len);
  462. lua_pushinteger(L, re);
  463. lua_pushinteger(L, len);
  464. return 2;
  465. }
  466. static int fatfs_remove(lua_State *L) {
  467. int luaType = lua_type(L, 1);
  468. if(luaType != LUA_TSTRING) {
  469. lua_pushinteger(L, -1);
  470. lua_pushstring(L, "file path must string");
  471. return 2;
  472. }
  473. FRESULT re = f_unlink(lua_tostring(L, 1));
  474. lua_pushinteger(L, re);
  475. return 1;
  476. }
  477. static int fatfs_rename(lua_State *L) {
  478. int luaType = lua_type(L, 1);
  479. if(luaType != LUA_TSTRING) {
  480. lua_pushinteger(L, -1);
  481. lua_pushstring(L, "source file path must string");
  482. return 2;
  483. }
  484. luaType = lua_type(L, 2);
  485. if(luaType != LUA_TSTRING) {
  486. lua_pushinteger(L, -1);
  487. lua_pushstring(L, "dest file path must string");
  488. return 2;
  489. }
  490. FRESULT re = f_rename(lua_tostring(L, 1), lua_tostring(L, 2));
  491. lua_pushinteger(L, re);
  492. return 1;
  493. }
  494. /**
  495. * fatfs.readfile("adc.txt")
  496. * fatfs.readfile("adc.txt", 512, 0) 默认只读取512字节,从0字节开始读
  497. */
  498. static int fatfs_readfile(lua_State *L) {
  499. int luaType = lua_type( L, 1);
  500. if(luaType != LUA_TSTRING) {
  501. lua_pushinteger(L, -1);
  502. lua_pushstring(L, "file path must string");
  503. return 2;
  504. }
  505. FIL fil;
  506. FRESULT re = f_open(&fil, lua_tostring(L, 1), FA_READ);
  507. if (re != FR_OK) {
  508. lua_pushinteger(L, re);
  509. return 1;
  510. }
  511. DWORD limit = luaL_optinteger(L, 2, 512);
  512. DWORD seek = luaL_optinteger(L, 3, 0);
  513. if (seek > 0) {
  514. f_lseek(&fil, seek);
  515. }
  516. BYTE buf[limit];
  517. size_t len;
  518. if (FATFS_DEBUG)
  519. LLOGD("[FatFS]readfile seek=%d limit=%d", seek, limit);
  520. FRESULT fr = f_read(&fil, buf, limit, &len);
  521. if (fr != FR_OK) {
  522. lua_pushinteger(L, -3);
  523. lua_pushinteger(L, fr);
  524. return 2;
  525. }
  526. f_close(&fil);
  527. lua_pushinteger(L, 0);
  528. lua_pushlstring(L, (const char*)buf, len);
  529. if (FATFS_DEBUG)
  530. LLOGD("[FatFS]readfile seek=%d limit=%d len=%d", seek, limit, len);
  531. return 2;
  532. }
  533. static int fatfs_debug_mode(lua_State *L) {
  534. FATFS_DEBUG = luaL_optinteger(L, 1, 1);
  535. return 0;
  536. }
  537. // Module function map
  538. #include "rotable2.h"
  539. static const rotable_Reg_t reg_fatfs[] =
  540. {
  541. { "init", ROREG_FUNC(fatfs_mount)}, //初始化,挂载, 别名方法
  542. { "mount", ROREG_FUNC(fatfs_mount)}, //初始化,挂载
  543. { "getfree", ROREG_FUNC(fatfs_getfree)}, // 获取文件系统大小,剩余空间
  544. #if 0
  545. { "unmount", ROREG_FUNC(fatfs_unmount)}, // 取消挂载
  546. { "mkfs", ROREG_FUNC(fatfs_mkfs)}, // 格式化!!!
  547. //{ "test", fatfs_test)},
  548. { "debug", ROREG_FUNC(fatfs_debug_mode)}, // 调试模式,打印更多日志
  549. { "lsdir", ROREG_FUNC(fatfs_lsdir)}, // 列举目录下的文件,名称,大小,日期,属性
  550. { "mkdir", ROREG_FUNC(fatfs_mkdir)}, // 列举目录下的文件,名称,大小,日期,属性
  551. { "stat", ROREG_FUNC(fatfs_stat)}, // 查询文件信息
  552. { "open", ROREG_FUNC(fatfs_open)}, // 打开一个文件句柄
  553. { "close", ROREG_FUNC(fatfs_close)}, // 关闭一个文件句柄
  554. { "seek", ROREG_FUNC(fatfs_seek)}, // 移动句柄的当前位置
  555. { "truncate", ROREG_FUNC(fatfs_truncate)}, // 缩减文件尺寸到当前seek位置
  556. { "read", ROREG_FUNC(fatfs_read)}, // 读取数据
  557. { "write", ROREG_FUNC(fatfs_write)}, // 写入数据
  558. { "remove", ROREG_FUNC(fatfs_remove)}, // 删除文件,别名方法
  559. { "unlink", ROREG_FUNC(fatfs_remove)}, // 删除文件
  560. { "rename", ROREG_FUNC(fatfs_rename)}, // 文件改名
  561. { "readfile", ROREG_FUNC(fatfs_readfile)}, // 读取文件的简易方法
  562. #endif
  563. { "SPI", ROREG_INT(DISK_SPI)},
  564. { "SDIO", ROREG_INT(DISK_SDIO)},
  565. { "RAM", ROREG_INT(DISK_RAM)},
  566. // { "USB", ROREG_INT(DISK_USB)},
  567. { NULL, ROREG_INT(0)}
  568. };
  569. int luaopen_fatfs( lua_State *L )
  570. {
  571. luat_newlib2(L, reg_fatfs);
  572. #ifdef LUAT_USE_FS_VFS
  573. luat_vfs_reg(&vfs_fs_fatfs);
  574. #endif
  575. return 1;
  576. }