Ver Fonte

add: 使得win32也支持sfd,以zbuff作为存储区域,模拟访问,为lfs-vfs的测试做准备

Wendal Chen há 4 anos atrás
pai
commit
6da504a6b7

+ 8 - 0
bsp/win32/CMakeLists.txt

@@ -30,6 +30,8 @@ ELSE ()
                           MM2_SRCS)
 ENDIF ()
 
+include_directories(${TOPROOT}/luat/packages/lfs)
+
 aux_source_directory(./port PORT_SRCS)
 aux_source_directory(${TOPROOT}/lua/src LUA_SRCS)
 #aux_source_directory(${TOPROOT}/luat/freertos FTOS_T_SRCS)
@@ -53,11 +55,17 @@ add_library(luat ${TOPROOT}/luat/modules/luat_main.c
                  ${TOPROOT}/luat/modules/luat_lib_mqttcore.c
                  ${TOPROOT}/luat/modules/luat_lib_libcoap.c
                  ${TOPROOT}/luat/modules/luat_lib_crypto.c
+                 ${TOPROOT}/luat/modules/luat_lib_sfd.c
+                 ${TOPROOT}/luat/modules/luat_sfd.c
                  ${TOPROOT}/luat/modules/crc.c
                  ${TOPROOT}/luat/vfs/luat_vfs.c
                  ${TOPROOT}/luat/vfs/luat_fs_luadb.c
                  ${TOPROOT}/luat/vfs/luat_fs_posix.c
                  ${TOPROOT}/luat/vfs/luat_luadb_inline.c
+                 ${TOPROOT}/luat/packages/lfs/lfs_sfd.c
+                 ${TOPROOT}/luat/packages/lfs/lfs_util.c
+                 ${TOPROOT}/luat/packages/lfs/lfs.c
+                 ${TOPROOT}/luat/packages/lfs/luat_lib_lfs2.c
             )
 
 IF (WIN32)

+ 1 - 0
bsp/win32/port/luat_base_win32.c

@@ -37,6 +37,7 @@ static const luaL_Reg loadedlibs[] = {
 #endif
   {"crypto", luaopen_crypto},
   {"fatfs", luaopen_fatfs},
+  {"lfs2",   luaopen_lfs2},
   {NULL, NULL}
 };
 

+ 1 - 0
luat/include/luat_base.h

@@ -108,6 +108,7 @@ LUAMOD_API int luaopen_dbg( lua_State *L );
 LUAMOD_API int luaopen_zbuff( lua_State *L );
 
 LUAMOD_API int luaopen_sfd( lua_State *L );
+LUAMOD_API int luaopen_lfs2( lua_State *L );
 
 /** sprintf需要支持longlong值的打印, 提供平台无关的实现*/
 int l_sprintf(char *buf, size_t size, const char *fmt, ...);

+ 13 - 6
luat/include/luat_sfd.h

@@ -1,7 +1,8 @@
 
 #include "luat_base.h"
 
-
+#include "luat_spi.h"
+#include "luat_zbuff.h"
 
 typedef struct sdf_opts {
     int (*initialize) (void* userdata);
@@ -12,13 +13,19 @@ typedef struct sdf_opts {
 	int (*ioctl) (void* userdata, size_t cmd, void* buff);
 }sdf_opts_t;
 
-typedef struct sfd_w25q {
+typedef struct sfd_drv {
     const sdf_opts_t* opts;
-    int spi_id;
-    int spi_cs;
+    uint8_t type;
+    union
+    {
+        struct sfd_spi {
+            int id;
+            int cs;
+        } spi;
+        luat_zbuff* zbuff;
+    } cfg;
     size_t sector_size;
     size_t sector_count;
     size_t erase_size;
     char chip_id[8];
-} sfd_w25q_t;
-
+} sfd_drv_t;

+ 71 - 49
luat/modules/luat_lib_sfd.c

@@ -13,117 +13,139 @@
 
 
 extern const sdf_opts_t sfd_w25q_opts;
+extern const sdf_opts_t sfd_mem_opts;
 
 /*
 初始化spi flash
-@api    sfd.init(spi_id, spi_cs)
-@int  SPI总线的id
-@int  SPI FLASH的片选脚对应的GPIO
+@api    sfd.init(type, spi_id, spi_cs)
+@string 类型, 可以是spi, 也可以是zbuff
+@int  SPI总线的id, 或者 zbuff实例
+@int  SPI FLASH的片选脚对应的GPIO, 当类型是spi时才需要传
 @return userdata 成功返回一个数据结构,否则返回nil
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "chip id", sfd.id(w25q):toHex())
+local drv = sfd.init("spi", 0, 17)
+if drv then
+    log.info("sfd", "chip id", sfd.id(drv):toHex())
 end
 */
 static int l_sfd_init(lua_State *L) {
-    int spi_id = luaL_checkinteger(L, 1);
-    int spi_cs = luaL_checkinteger(L, 2);
-
-    sfd_w25q_t *w25q = (sfd_w25q_t *)lua_newuserdata(L, sizeof(sfd_w25q_t));
-    memset(w25q, 0, sizeof(sfd_w25q_t));
-    w25q->spi_id = spi_id;
-    w25q->spi_cs = spi_cs;
-    w25q->opts = &sfd_w25q_opts;
-
-    int re = w25q->opts->initialize(w25q);
-    if (re == 0) {
-        return 1;
+
+    const char* type = luaL_checkstring(L, 1);
+#ifndef LUA_USE_WINDOWS
+    if (!strcmp("spi", type)) {
+        
+        int spi_id = luaL_checkinteger(L, 2);
+        int spi_cs = luaL_checkinteger(L, 3);
+
+        sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
+        memset(drv, 0, sizeof(sfd_drv_t));
+        drv->cfg.spi.id = spi_id;
+        drv->cfg.spi.cs = spi_cs;
+        drv->opts = &sfd_w25q_opts;
+        drv->type = 0;
+
+        int re = drv->opts->initialize(drv);
+        if (re == 0) {
+            return 1;
+        }
+    }
+#endif
+    if (!strcmp("zbuff", type)) {
+        sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
+        memset(drv, 0, sizeof(sfd_drv_t));
+        drv->type = 1;
+        drv->cfg.zbuff = luaL_checkudata(L, 2, "ZBUFF*");
+        drv->opts = &sfd_mem_opts;
+
+        int re = drv->opts->initialize(drv);
+        if (re == 0) {
+            return 1;
+        }
     }
     return 0;
 }
 
 /*
 检查spi flash状态
-@api    sfd.status(w25q)
+@api    sfd.status(drv)
 @userdata  sfd.init返回的数据结构
 @return int 状态值,0 未初始化成功,1初始化成功且空闲,2正忙
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "status", sfd.status(w25q))
+local drv = sfd.init(0, 17)
+if drv then
+    log.info("sfd", "status", sfd.status(drv))
 end
 */
 static int l_sfd_status(lua_State *L) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *) lua_touserdata(L, 1);
-    lua_pushinteger(L, w25q->opts->status(w25q));
+    sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
+    lua_pushinteger(L, drv->opts->status(drv));
     return 1;
 }
 
 /*
 读取数据
-@api    sfd.read(w25q, offset, len)
+@api    sfd.read(drv, offset, len)
 @userdata  sfd.init返回的数据结构
 @int    起始偏移量
 @int    读取长度,当前限制在256以内
 @return string 数据
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "read", sfd.read(w25q, 0x100, 256))
+local drv = sfd.init(0, 17)
+if drv then
+    log.info("sfd", "read", sfd.read(drv, 0x100, 256))
 end
 */
 static int l_sfd_read(lua_State *L) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *) lua_touserdata(L, 1);
+    sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
     size_t offset = luaL_checkinteger(L, 2);
     size_t len = luaL_checkinteger(L, 3);
     luaL_Buffer buff;
     luaL_buffinitsize(L, &buff, len);
-    w25q->opts->read(w25q, buff.b, offset, len);
+    drv->opts->read(drv, buff.b, offset, len);
     luaL_pushresult(&buff);
     return 1;
 }
 
 /*
 写入数据
-@api    sfd.write(w25q, offset, data)
+@api    sfd.write(drv, offset, data)
 @userdata  sfd.init返回的数据结构
 @int    起始偏移量
 @string    需要写入的数据,当前支持256字节及以下
 @return boolean 成功返回true,失败返回false
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "write", sfd.write(w25q, 0x100, "hi,luatos"))
+local drv = sfd.init(0, 17)
+if drv then
+    log.info("sfd", "write", sfd.write(drv, 0x100, "hi,luatos"))
 end
 */
 static int l_sfd_write(lua_State *L) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *) lua_touserdata(L, 1);
+    sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
     size_t offset = luaL_checkinteger(L,2);
     size_t len = 0;
     const char* buff = luaL_checklstring(L, 3, &len);
-    int re = w25q->opts->write(w25q, buff, offset, len);
+    int re = drv->opts->write(drv, buff, offset, len);
     lua_pushboolean(L, re == 0 ? 1 : 0);
     return 1;
 }
 
 /*
 写入数据
-@api    sfd.erase(w25q, offset)
+@api    sfd.erase(drv, offset)
 @userdata  sfd.init返回的数据结构
 @int    起始偏移量
 @return boolean 成功返回true,失败返回false
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "write", sfd.erase(w25q, 0x100))
+local drv = sfd.init(0, 17)
+if drv then
+    log.info("sfd", "write", sfd.erase(drv, 0x100))
 end
 */
 static int l_sfd_erase(lua_State *L) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *) lua_touserdata(L, 1);
-    size_t offset = luaL_checkinteger(L,2);
+    sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
+    size_t offset = luaL_checkinteger(L, 2);
     size_t len = luaL_optinteger(L, 3, 4096);
-    int re = w25q->opts->erase(w25q, offset, len);
+    int re = drv->opts->erase(drv, offset, len);
     lua_pushboolean(L, re == 0 ? 1 : 0);
     return 1;
 }
@@ -134,18 +156,18 @@ static int l_sfd_ioctl(lua_State *L) {
 
 /*
 芯片唯一id
-@api    sfd.id(w25q)
+@api    sfd.id(drv)
 @userdata  sfd.init返回的数据结构
 @return string 8字节(64bit)的芯片id
 @usage
-local w25q = sfd.init(0, 17)
-if w25q then
-    log.info("sfd", "chip id", sfd.id(w25q))
+local drv = sfd.init(0, 17)
+if drv then
+    log.info("sfd", "chip id", sfd.id(drv))
 end
 */
 static int l_sfd_id(lua_State *L) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *) lua_touserdata(L, 1);
-    lua_pushlstring(L, w25q->chip_id, 8);
+    sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
+    lua_pushlstring(L, drv->chip_id, 8);
     return 1;
 }
 

+ 139 - 37
luat/modules/luat_sfd.c

@@ -11,7 +11,7 @@
 #define CS_H(pin) luat_gpio_set(pin, 1)
 #define CS_L(pin) luat_gpio_set(pin, 0)
 
-// 针对W25Q的实现
+// 针对drv的实现
 
 static int sfd_w25q_init (void* userdata);
 static int sfd_w25q_status (void* userdata);
@@ -30,14 +30,14 @@ const sdf_opts_t sfd_w25q_opts = {
 };
 
 static int sfd_w25q_init (void* userdata) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)userdata;
+    sfd_drv_t *drv = (sfd_drv_t *)userdata;
     uint8_t cmd = 0x9F;
     // 发送CMD 9F, 读取容量信息
-    luat_gpio_set(w25q->spi_cs, 0);
-    luat_spi_send(w25q->spi_id, (const char*)&cmd, 1);
+    luat_gpio_set(drv->cfg.spi.cs, 0);
+    luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, 1);
     char buff[3] = {0};
-    luat_spi_recv(w25q->spi_id, buff, 3);
-    luat_gpio_set(w25q->spi_cs, 1);
+    luat_spi_recv(drv->cfg.spi.id, buff, 3);
+    luat_gpio_set(drv->cfg.spi.cs, 1);
     if (buff[0] != 0x40) {
         LLOGW("can't read spi flash: cmd 9F");
         return -1;
@@ -46,81 +46,183 @@ static int sfd_w25q_init (void* userdata) {
     if (buff[1] == 0xEF) {
         switch(buff[2]) {
             case 0x13:
-                w25q->sector_count = 8*256;// w25q80, 8M
+                drv->sector_count = 8*256;// drv80, 8M
                 break;
             case 0x14:
-                w25q->sector_count = 16*256;// w25q16, 16M
+                drv->sector_count = 16*256;// drv16, 16M
                 break;
             case 0x15:
-                w25q->sector_count = 32*256;// w25q32, 32M
+                drv->sector_count = 32*256;// drv32, 32M
                 break;
             case 0x16:
-                w25q->sector_count = 64*256;// w25q64, 64M
+                drv->sector_count = 64*256;// drv64, 64M
                 break;
             case 0x17:
-                w25q->sector_count = 128*256;// w25q128, 128M
+                drv->sector_count = 128*256;// drv128, 128M
                 break;
             case 0x18:
-                w25q->sector_count = 256*256;// w25q256, 256M
+                drv->sector_count = 256*256;// drv256, 256M
                 break;
             case 0x19:
-                w25q->sector_count = 512*256;// w25q512, 512M
+                drv->sector_count = 512*256;// drv512, 512M
                 break;
             default :
-                w25q->sector_count = 16*256;// 默认当16M吧
+                drv->sector_count = 16*256;// 默认当16M吧
                 break;
         }
     }
     else {
-        w25q->sector_count = 16*256;// 默认当16M吧
+        drv->sector_count = 16*256;// 默认当16M吧
     }
-    //w25q->flash_id[0] = buff[1];
-    //w25q->flash_id[1] = buff[2];
+    //drv->flash_id[0] = buff[1];
+    //drv->flash_id[1] = buff[2];
 
     // 读设备唯一id
-    luat_gpio_set(w25q->spi_cs, 0);
+    luat_gpio_set(drv->cfg.spi.cs, 0);
     char chip_id_cmd[] = {0x4B, 0x00, 0x00, 0x00, 0x00};
-    luat_spi_send(w25q->spi_id, chip_id_cmd, 5);
-    luat_spi_read(w25q->spi_id, w25q->chip_id, 8);
-    luat_gpio_set(w25q->spi_cs, 1);
+    luat_spi_send(drv->cfg.spi.id, chip_id_cmd, 5);
+    luat_spi_read(drv->cfg.spi.id, drv->chip_id, 8);
+    luat_gpio_set(drv->cfg.spi.cs, 1);
 
     return 0;
 }
 
 static int sfd_w25q_status (void* userdata) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)userdata;
-    return w25q->sector_count == 0 ? 0 : 1; // TODO 根据BUSY 状态返回
+    sfd_drv_t *drv = (sfd_drv_t *)userdata;
+    return drv->sector_count == 0 ? 0 : 1; // TODO 根据BUSY 状态返回
 }
 
 static int sfd_w25q_read (void* userdata, char* buff, size_t offset, size_t len) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)userdata;
+    sfd_drv_t *drv = (sfd_drv_t *)userdata;
     char cmd[4] = {0x03, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
-    luat_gpio_set(w25q->spi_cs, 0);
-    luat_spi_send(w25q->spi_id, (const char*)&cmd, 4);
-    luat_spi_read(w25q->spi_id, buff, len);
-    luat_gpio_set(w25q->spi_cs, 1);
+    luat_gpio_set(drv->cfg.spi.cs, 0);
+    luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, 4);
+    luat_spi_read(drv->cfg.spi.id, buff, len);
+    luat_gpio_set(drv->cfg.spi.cs, 1);
     return 0;
 }
 
 static int sfd_w25q_write (void* userdata, const char* buff, size_t offset, size_t len) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)userdata;
+    sfd_drv_t *drv = (sfd_drv_t *)userdata;
     char cmd[4] = {0x02, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
-    luat_gpio_set(w25q->spi_cs, 0);
-    luat_spi_send(w25q->spi_id, (const char*)&cmd, 4);
-    luat_spi_send(w25q->spi_id, buff, len);
-    luat_gpio_set(w25q->spi_cs, 1);
+    luat_gpio_set(drv->cfg.spi.cs, 0);
+    luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, 4);
+    luat_spi_send(drv->cfg.spi.id, buff, len);
+    luat_gpio_set(drv->cfg.spi.cs, 1);
     return 0;
 }
 
 static int sfd_w25q_erase (void* userdata, size_t offset, size_t len) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)userdata;
+    sfd_drv_t *drv = (sfd_drv_t *)userdata;
     char cmd[4] = {0x20, offset >> 16, (offset >> 8) & 0xFF, offset & 0xFF};
-    luat_gpio_set(w25q->spi_cs, 0);
-    luat_spi_send(w25q->spi_id, (const char*)&cmd, 4);
-    luat_gpio_set(w25q->spi_cs, 1);
+    luat_gpio_set(drv->cfg.spi.cs, 0);
+    luat_spi_send(drv->cfg.spi.id, (const char*)&cmd, 4);
+    luat_gpio_set(drv->cfg.spi.cs, 1);
     return 0;
 }
 
 static int sfd_w25q_ioctl (void* userdata, size_t cmd, void* buff) {
     return -1;
 }
+
+
+//--------------------------------------------------------------------
+// SFD at memory ,  for test
+#include "luat_zbuff.h"
+
+static int sfd_mem_init (void* userdata);
+static int sfd_mem_status (void* userdata);
+static int sfd_mem_read (void* userdata, char* buff, size_t offset, size_t len);
+static int sfd_mem_write (void* userdata, const char* buff, size_t offset, size_t len);
+static int sfd_mem_erase (void* userdata, size_t offset, size_t len);
+static int sfd_mem_ioctl (void* userdata, size_t cmd, void* buff);
+
+const sdf_opts_t sfd_mem_opts = {
+    .initialize = sfd_mem_init,
+    .status = sfd_mem_status,
+    .read = sfd_mem_read,
+    .write = sfd_mem_write,
+    .erase = sfd_mem_erase,
+    .ioctl = sfd_mem_ioctl,
+};
+
+static int sfd_mem_init (void* userdata) {
+    if (userdata == NULL) {
+        LLOGE("userdata for sfd_mem must NOT NULL");
+        return -1;
+    }
+    sfd_drv_t *drv = (sfd_drv_t*)userdata;
+    luat_zbuff* zbuff = drv->cfg.zbuff;
+    if (zbuff->len < 16*1024) {
+        LLOGE("zbuff for sfd_mem is too small");
+        return -1;
+    }
+    return 0;
+}
+static int sfd_mem_status (void* userdata) {
+    if (userdata == NULL) {
+        LLOGE("userdata for sfd_mem must NOT NULL");
+        return -1;
+    }
+    return 0;
+}
+static int sfd_mem_read (void* userdata, char* buff, size_t offset, size_t len) {
+    if (userdata == NULL) {
+        LLOGE("userdata for sfd_mem must NOT NULL");
+        return -1;
+    }
+    sfd_drv_t *drv = (sfd_drv_t*)userdata;
+    luat_zbuff* zbuff = drv->cfg.zbuff;
+    if (offset > zbuff->len) {
+        // LLOGD("over read");
+        return 0;
+    }
+    if (offset+len > zbuff->len) {
+        len = zbuff->len  - offset;
+    }
+    if (len > 0) {
+        memcpy(buff, zbuff->addr + offset, len);
+    }
+    return len;
+}
+static int sfd_mem_write (void* userdata, const char* buff, size_t offset, size_t len) {
+    if (userdata == NULL) {
+        LLOGE("userdata for sfd_mem must NOT NULL");
+        return -1;
+    }
+    sfd_drv_t *drv = (sfd_drv_t*)userdata;
+    luat_zbuff* zbuff = drv->cfg.zbuff;
+    if (offset > zbuff->len) {
+        // LLOGD("over read");
+        return 0;
+    }
+    if (offset+len > zbuff->len) {
+        len = zbuff->len  - offset;
+    }
+    if (len > 0) {
+        memcpy(zbuff->addr + offset, buff, len);
+    }
+    return len;
+}
+static int sfd_mem_erase (void* userdata, size_t offset, size_t len) {
+    if (userdata == NULL) {
+        LLOGE("userdata for sfd_mem must NOT NULL");
+        return -1;
+    }
+    sfd_drv_t *drv = (sfd_drv_t*)userdata;
+    luat_zbuff* zbuff = drv->cfg.zbuff;
+    if (offset > zbuff->len) {
+        // LLOGD("over read");
+        return 0;
+    }
+    if (offset+len > zbuff->len) {
+        len = zbuff->len  - offset;
+    }
+    if (len > 0) {
+        memset(zbuff->addr + offset, 0, len);
+    }
+    return 0;
+}
+static int sfd_mem_ioctl (void* userdata, size_t cmd, void* buff) {
+    return 0;
+}

+ 8 - 8
luat/packages/lfs/lfs_sfd.c

@@ -12,16 +12,16 @@
 #include "luat_log.h"
 
 int lfs_sfd_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)c->context;
-    return w25q->opts->read(w25q, buffer, block*4096+off, size);
+    sfd_drv_t *drv = (sfd_drv_t *)c->context;
+    return drv->opts->read(drv, buffer, block*4096+off, size);
 }
 
     // Program a region in a block. The block must have previously
     // been erased. Negative error codes are propogated to the user.
     // May return LFS_ERR_CORRUPT if the block should be considered bad.
 int lfs_sfd_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)c->context;
-    return w25q->opts->write(w25q, buffer, block*4096+off, size);
+    sfd_drv_t *drv = (sfd_drv_t *)c->context;
+    return drv->opts->write(drv, buffer, block*4096+off, size);
 }
 
     // Erase a block. A block must be erased before being programmed.
@@ -29,14 +29,14 @@ int lfs_sfd_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, c
     // are propogated to the user.
     // May return LFS_ERR_CORRUPT if the block should be considered bad.
 int lfs_sfd_erase(const struct lfs_config *c, lfs_block_t block) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)c->context;
-    return w25q->opts->erase(w25q, block*4096, 4096);
+    sfd_drv_t *drv = (sfd_drv_t *)c->context;
+    return drv->opts->erase(drv, block*4096, 4096);
 }
 
     // Sync the state of the underlying block device. Negative error codes
     // are propogated to the user.
 int lfs_sfd_sync(const struct lfs_config *c) {
-    sfd_w25q_t *w25q = (sfd_w25q_t *)c->context;
-    //w25q->opts->ioctl(w25q, ???);
+    sfd_drv_t *drv = (sfd_drv_t *)c->context;
+    //drv->opts->ioctl(drv, ???);
     return 0;
 }

+ 53 - 8
luat/packages/lfs/luat_lib_lfs2.c

@@ -6,6 +6,9 @@
 #include "luat_gpio.h"
 #include "luat_malloc.h"
 
+#define LUAT_LOG_TAG "lfs2"
+#include "luat_log.h"
+
 #include "lfs.h"
 
 int lfs_sfd_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);
@@ -18,17 +21,29 @@ typedef struct lfs2_mount {
     void* userdata;
     int luaref;
     lfs_t* fs;
+    struct lfs_config* cfg;
 }lfs2_mount_t;
 
 static lfs2_mount_t mounted[2] = {0};
 
+/**
+挂载lifftefs,当前支持spi flash 和 memory 两种
+@string 挂载类型, 当前支持sfd和mem两种
+@string 挂载路径
+@userdata 挂载所需要的额外数据, 当前仅支持sfd
+@usage
+local drv = sfd.init(0, 18)
+if drv then
+  local fs = lfs2.mount("/sfd", drv)
+end
+*/
 static int l_lfs2_mount(lua_State *L) {
     const char* path = luaL_checkstring(L, 1);
-    sfd_w25q_t *w25q = lua_touserdata(L, 2);
+    sfd_drv_t *drv = lua_touserdata(L, 2);
     for (size_t i = 0; i < 2; i++)
     {
         if (mounted[i].userdata == NULL) {
-            mounted[i].userdata = w25q;
+            mounted[i].userdata = drv;
             memcpy(mounted[i].path, path, strlen(path) + 1);
             
             lua_settop(L, 2);
@@ -36,6 +51,7 @@ static int l_lfs2_mount(lua_State *L) {
             
             mounted[i].fs = luat_heap_malloc(sizeof(lfs_t));
             struct lfs_config* cfg = (struct lfs_config*)luat_heap_malloc(sizeof(struct lfs_config));
+            mounted[i].cfg = cfg;
 
             memset(cfg, 0, sizeof(struct lfs_config));
             memset(mounted[i].fs, 0, sizeof(lfs_t));
@@ -48,19 +64,19 @@ static int l_lfs2_mount(lua_State *L) {
             cfg->read_size = 256;
             cfg->prog_size = 256;
             cfg->block_size = 4096;
-            cfg->block_count = w25q->sector_count / 16;
+            cfg->block_count = drv->sector_count / 16;
             cfg->block_cycles = 200;
             cfg->cache_size = 16;
             cfg->lookahead_size = 256;
 
-            // cfg.read_buffer = lfs_read_buf,
-            // cfg.prog_buffer = lfs_prog_buf,
-            // cfg.lookahead_buffer = lfs_lookahead_buf,
+            cfg->read_buffer = luat_heap_malloc(256);
+            cfg->prog_buffer = luat_heap_malloc(256);
+            cfg->lookahead_buffer = luat_heap_malloc(256);
             cfg->name_max = 63;
             cfg->file_max = 0;
             cfg->attr_max = 0;
 
-            cfg->context = w25q;
+            cfg->context = drv;
 
             int ret = lfs_mount(mounted[i].fs, cfg);
             if (ret)
@@ -72,13 +88,42 @@ static int l_lfs2_mount(lua_State *L) {
     return 0;
 }
 
+/**
+格式化为lifftefs
+@api lfs2.mount(path)
+@string 挂载路径
+@usage
+local drv = sfd.init("spi", 0, 18)
+if drv then
+  local fs = lfs2.mount("sfd", "/sfd", drv)
+  if fs then
+    lfs2.mkfs(fs)
+  end
+end
+*/
+static int l_lfs2_mkfs(lua_State *L) {
+  const char* path = luaL_checkstring(L, 1);
+  for (size_t i = 0; i < 2; i++) {
+    if (mounted[i].userdata == NULL)
+      continue;
+    if (!strcmp(mounted[i].path, path)) {
+      int ret = lfs_format(mounted[i].fs, mounted[i].cfg);
+      LLOGD("lfs_format ret %d", ret);
+      lua_pushboolean(L, ret == 0 ? 1 : 0);
+      return 1;
+    }
+  }
+  LLOGW("not path match, ignore mkfs");
+  return 0;
+}
+
 
 #include "rotable.h"
 static const rotable_Reg reg_lfs2[] =
 { 
   { "mount",	l_lfs2_mount, 0}, //初始化,挂载
 //   { "unmount",	l_lfs2_unmount, 0}, // 取消挂载
-//   { "mkfs",		l_lfs2_mkfs, 0}, // 格式化!!!
+  { "mkfs",		l_lfs2_mkfs, 0}, // 格式化!!!
 //   //{ "test",  l_lfs2_test, 0},
 //   { "getfree",	l_lfs2_getfree, 0}, // 获取文件系统大小,剩余空间
 //   { "debug",	l_lfs2_debug_mode, 0}, // 调试模式,打印更多日志