luat_lib_lfs2.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "luat_base.h"
  2. #include "luat_sfd.h"
  3. #include "luat_spi.h"
  4. #include "luat_gpio.h"
  5. #include "luat_mem.h"
  6. #include "luat_fs.h"
  7. #define LUAT_LOG_TAG "lfs2"
  8. #include "luat_log.h"
  9. #include "lfs.h"
  10. #ifdef LUAT_USE_FS_VFS
  11. extern const struct luat_vfs_filesystem vfs_fs_lfs2;
  12. #endif
  13. int lfs_sfd_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
  14. int lfs_sfd_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size);
  15. int lfs_sfd_erase(const struct lfs_config *c, lfs_block_t block);
  16. int lfs_sfd_sync(const struct lfs_config *c);
  17. typedef struct lfs2_mount {
  18. char path[16];
  19. void* userdata;
  20. int luaref;
  21. lfs_t* fs;
  22. struct lfs_config* cfg;
  23. }lfs2_mount_t;
  24. static lfs2_mount_t mounted[2] = {0};
  25. /**
  26. 挂载lifftefs,当前支持spi flash 和 memory 两种
  27. @api lfs2.mount(path, drv, formatOnFail)
  28. @string 挂载路径
  29. @userdata 挂载所需要的额外数据, 当前仅支持sfd
  30. @bool 挂载失败时是否尝试格式化,默认为false
  31. @usage
  32. local drv = sfd.init(0, 18)
  33. if drv then
  34. local fs = lfs2.mount("/sfd", drv, true)
  35. end
  36. */
  37. static int l_lfs2_mount(lua_State *L) {
  38. const char* path = luaL_checkstring(L, 1);
  39. sfd_drv_t *drv = lua_touserdata(L, 2);
  40. bool formatOnFail = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false;
  41. for (size_t i = 0; i < 2; i++)
  42. {
  43. if (mounted[i].userdata == NULL) {
  44. mounted[i].userdata = drv;
  45. memcpy(mounted[i].path, path, strlen(path) + 1);
  46. lua_settop(L, 2);
  47. mounted[i].luaref = luaL_ref(L, LUA_REGISTRYINDEX);
  48. mounted[i].fs = luat_heap_malloc(sizeof(lfs_t));
  49. struct lfs_config* cfg = (struct lfs_config*)luat_heap_malloc(sizeof(struct lfs_config));
  50. mounted[i].cfg = cfg;
  51. memset(cfg, 0, sizeof(struct lfs_config));
  52. memset(mounted[i].fs, 0, sizeof(lfs_t));
  53. cfg->read = lfs_sfd_read;
  54. cfg->prog = lfs_sfd_prog;
  55. cfg->erase = lfs_sfd_erase;
  56. cfg->sync = lfs_sfd_sync;
  57. cfg->read_size = 256;
  58. cfg->prog_size = 256;
  59. cfg->block_size = 4096;
  60. cfg->block_count = drv->sector_count / 16;
  61. cfg->block_cycles = 200;
  62. cfg->cache_size = 256;
  63. cfg->lookahead_size = 16;
  64. cfg->read_buffer = luat_heap_malloc(256);
  65. cfg->prog_buffer = luat_heap_malloc(256);
  66. cfg->lookahead_buffer = luat_heap_malloc(256);
  67. cfg->name_max = 63;
  68. cfg->file_max = 0;
  69. cfg->attr_max = 0;
  70. cfg->context = drv;
  71. int ret = lfs_mount(mounted[i].fs, cfg);
  72. LLOGW("lfs_mount ret %d", ret);
  73. if (ret < 0 && formatOnFail) {
  74. if (lfs_format(mounted[i].fs, cfg) == 0) {
  75. ret = lfs_mount(mounted[i].fs, cfg);
  76. }
  77. }
  78. if (ret < 0) {
  79. luat_heap_free(cfg->lookahead_buffer);
  80. luat_heap_free(cfg->prog_buffer);
  81. luat_heap_free(cfg->read_buffer);
  82. luat_heap_free(cfg);
  83. luat_heap_free(mounted[i].fs);
  84. mounted[i].fs = NULL;
  85. mounted[i].cfg = NULL;
  86. mounted[i].userdata = NULL;
  87. }
  88. else {
  89. #ifdef LUAT_USE_FS_VFS
  90. //char mount_point[16] = {0};
  91. //memcpy(mount_point, "/lfs2", strlen("/lfs2"));
  92. //memcpy(mount_point + strlen("/lfs2"), path, strlen(path));
  93. luat_fs_conf_t conf2 = {
  94. .busname = (char*)mounted[i].fs,
  95. .type = "lfs2",
  96. .filesystem = "lfs2",
  97. .mount_point = path,
  98. };
  99. luat_fs_mount(&conf2);
  100. #endif
  101. }
  102. lua_pushboolean(L, ret >= 0 ? 1 : 0);
  103. return 1;
  104. }
  105. }
  106. LLOGW("only 2 mount is allow");
  107. return 0;
  108. }
  109. /**
  110. 格式化为lifftefs
  111. @api lfs2.mount(path)
  112. @string 挂载路径
  113. @usage
  114. local drv = sfd.init("spi", 0, 18)
  115. if drv then
  116. local fs = lfs2.mount("sfd", "/sfd", drv)
  117. if fs then
  118. lfs2.mkfs(fs)
  119. end
  120. end
  121. */
  122. static int l_lfs2_mkfs(lua_State *L) {
  123. const char* path = luaL_checkstring(L, 1);
  124. for (size_t i = 0; i < 2; i++) {
  125. if (mounted[i].userdata == NULL)
  126. continue;
  127. if (!strcmp(mounted[i].path, path)) {
  128. int ret = lfs_format(mounted[i].fs, mounted[i].cfg);
  129. LLOGD("lfs_format ret %d", ret);
  130. lua_pushboolean(L, ret == 0 ? 1 : 0);
  131. return 1;
  132. }
  133. }
  134. LLOGW("not path match, ignore mkfs");
  135. return 0;
  136. }
  137. #include "rotable2.h"
  138. static const rotable_Reg_t reg_lfs2[] =
  139. {
  140. { "mount", ROREG_FUNC(l_lfs2_mount)}, //初始化,挂载
  141. // { "unmount", ROREG_FUNC(l_lfs2_unmount)}, // 取消挂载
  142. { "mkfs", ROREG_FUNC(l_lfs2_mkfs)}, // 格式化!!!
  143. { NULL, ROREG_INT(0)}
  144. };
  145. int luaopen_lfs2( lua_State *L )
  146. {
  147. luat_newlib2(L, reg_lfs2);
  148. #ifdef LUAT_USE_FS_VFS
  149. luat_vfs_reg(&vfs_fs_lfs2);
  150. #endif
  151. return 1;
  152. }