luat_lib_fatfs.c 19 KB

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