Просмотр исходного кода

update: 优化fskv的实现,优化sfd抽象层

Wendal Chen 3 лет назад
Родитель
Сommit
f51e8f228b

+ 15 - 141
components/fskv/luat_fskv.c

@@ -9,173 +9,47 @@
 
 #include "lfs.h"
 
-luat_fskv_t* fskv;
-
-static sfd_onchip_t onchip;
-
-int sfd_onchip_init (void* userdata);
-int sfd_onchip_status (void* userdata);
-int sfd_onchip_read (void* userdata, char* buff, size_t offset, size_t len);
-int sfd_onchip_write (void* userdata, const char* buff, size_t offset, size_t len);
-int sfd_onchip_erase (void* userdata, size_t offset, size_t len);
-int sfd_onchip_ioctl (void* userdata, size_t cmd, void* buff);
-
-// Read a block
-static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
-        lfs_off_t off, void *buffer, lfs_size_t size) {
-    int ret = sfd_onchip_read(&onchip, buffer, block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
-    // LLOGD("sfd read %d %d %d %d", block, off, size, ret);
-    if (ret >= 0) {
-        // LLOGD("block_device_read return LFS_ERR_OK");
-        return LFS_ERR_OK;
-    }
-    // LLOGD("block_device_read return LFS_ERR_IO");
-    return LFS_ERR_IO;
-}
-
-// Program a block
-//
-// The block must have previously been erased.
-static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
-        lfs_off_t off, const void *buffer, lfs_size_t size) {
-    int ret = sfd_onchip_write(&onchip, buffer, block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
-    // LLOGD("sfd write %d %d %d %d", block, off, size, ret);
-    if (ret >= 0) {
-        // LLOGD("block_device_prog return LFS_ERR_OK");
-        return LFS_ERR_OK;
-    }
-    // LLOGD("block_device_prog return LFS_ERR_IO");
-    return LFS_ERR_IO;
-}
-
-// Erase a block
-//
-// A block must be erased before being programmed. The
-// state of an erased block is undefined.
-static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block) {
-    int ret = sfd_onchip_erase(&onchip, block * LFS_BLOCK_DEVICE_ERASE_SIZE, LFS_BLOCK_DEVICE_ERASE_SIZE);
-    // LLOGD("sfd erase %d %d", block, ret);
-    (void)ret;
-    return 0;
-}
-
-// Sync the block device
-static int block_device_sync(const struct lfs_config *cfg) {
-    return 0;
-}
-
-int luat_fskv_init(void) {
-    int ret = 0;
-    if (fskv == NULL) {
-        fskv = luat_heap_malloc(sizeof(luat_fskv_t));
-        if (fskv == NULL) {
-            LLOGE("out of memory when malloc fskv");
-            return -1;
-        }
-        memset(fskv, 0, sizeof(luat_fskv_t));
-        fskv->conf.read = block_device_read;
-        fskv->conf.prog = block_device_prog;
-        fskv->conf.erase = block_device_erase;
-        fskv->conf.sync = block_device_sync;
-        fskv->conf.attr_max = 0;
-        fskv->conf.file_max = 4096;
-        fskv->conf.block_count = (LFS_BLOCK_DEVICE_TOTOAL_SIZE) / LFS_BLOCK_DEVICE_ERASE_SIZE;
-        fskv->conf.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
-        fskv->conf.block_cycles = 200;
-        fskv->conf.name_max = 63;
-        fskv->conf.read_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
-        fskv->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
-        fskv->conf.prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
-        fskv->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
-        fskv->conf.lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
-        fskv->conf.lookahead_buffer = fskv->lookahead_buffer;
-        fskv->conf.prog_buffer = fskv->prog_buffer;
-        fskv->conf.read_buffer = fskv->read_buffer;
-
-        // LLOGD("fskv->conf.block_count %d", fskv->conf.block_count);
-        // LLOGD("fskv->conf.block_size %d", fskv->conf.block_size);
-        // LLOGD("fskv->conf.read_size %d", fskv->conf.read_size);
-        // LLOGD("fskv->conf.prog_size %d", fskv->conf.prog_size);
-        // LLOGD("fskv->conf.cache_size %d", fskv->conf.cache_size);
-
-        onchip.block_count = fskv->conf.block_count;
-        onchip.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
-        memcpy(onchip.name, "fskv", 5);
-        sfd_onchip_init(&onchip);
-
-        // block_device_read(NULL, 0, 0, fskv->prog_buffer, 256);
-        // LLOGD("Flash starts %02X %02X %02X %02X", fskv->prog_buffer[0], fskv->prog_buffer[1], 
-        //                                        fskv->prog_buffer[2], fskv->prog_buffer[3]);
-        // if (fskv->prog_buffer[0] == 0x00 && fskv->prog_buffer[1] == 0x00 && 
-        //     fskv->prog_buffer[2] == 245 && fskv->prog_buffer[3] == 256) {
-
-        //     }
-        // sfd_onchip_erase(NULL, 0, LFS_BLOCK_DEVICE_TOTOAL_SIZE);
-
-        ret = lfs_mount(&fskv->lfs, &fskv->conf);
-        if (ret != LFS_ERR_OK) {
-            LLOGI("fskv mount ret %d, exe auto-format", ret);
-            ret = lfs_format(&fskv->lfs, &fskv->conf);
-            if (ret != LFS_ERR_OK) {
-                luat_heap_free(fskv);
-                fskv = NULL;
-                LLOGE("fskv auto-format ret %d", ret);
-                return ret;
-            }
-            ret = lfs_mount(&fskv->lfs, &fskv->conf);
-            if (ret != LFS_ERR_OK) {
-                luat_heap_free(fskv);
-                fskv = NULL;
-                LLOGE("fskv remount ret %d", ret);
-                return ret;
-            }
-        }
-        LLOGD("init ok");
-    }
-    return 0;
-}
-
+// TODO 应该对接vfs, 而非直接对接lfs
+extern luat_sfd_lfs_t* sfd_lfs;
 
 int luat_fskv_del(const char* key) {
-    lfs_remove(&fskv->lfs, key);
+    lfs_remove(&sfd_lfs->lfs, key);
     return 0;
 }
 
 int luat_fskv_set(const char* key, void* data, size_t len) {
     lfs_file_t fd = {0};
     int ret = 0;
-    ret = lfs_file_open(&fskv->lfs, &fd, key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
+    ret = lfs_file_open(&sfd_lfs->lfs, &fd, key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
     if (ret != LFS_ERR_OK) {
         return -1;
     }
-    ret = lfs_file_write(&fskv->lfs, &fd, data, len);
-    lfs_file_close(&fskv->lfs, &fd);
+    ret = lfs_file_write(&sfd_lfs->lfs, &fd, data, len);
+    lfs_file_close(&sfd_lfs->lfs, &fd);
     return ret;
 }
 
 int luat_fskv_get(const char* key, void* data, size_t len) {
     lfs_file_t fd = {0};
     int ret = 0;
-    ret = lfs_file_open(&fskv->lfs, &fd, key, LFS_O_RDONLY);
+    ret = lfs_file_open(&sfd_lfs->lfs, &fd, key, LFS_O_RDONLY);
     if (ret != LFS_ERR_OK) {
         return 0;
     }
-    ret = lfs_file_read(&fskv->lfs, &fd, data, len);
-    lfs_file_close(&fskv->lfs, &fd);
+    ret = lfs_file_read(&sfd_lfs->lfs, &fd, data, len);
+    lfs_file_close(&sfd_lfs->lfs, &fd);
     return ret > 0 ? ret : 0;
 }
 
 int luat_fskv_clear(void) {
     int ret = 0;
-    ret = lfs_format(&fskv->lfs, &fskv->conf);
+    ret = lfs_format(&sfd_lfs->lfs, &sfd_lfs->conf);
     if (ret != LFS_ERR_OK) {
-        luat_heap_free(fskv);
         LLOGE("fskv clear ret %d", ret);
         return ret;
     }
-    ret = lfs_mount(&fskv->lfs, &fskv->conf);
+    ret = lfs_mount(&sfd_lfs->lfs, &sfd_lfs->conf);
     if (ret != LFS_ERR_OK) {
-        luat_heap_free(fskv);
         LLOGE("fskv reinit ret %d", ret);
         return ret;
     }
@@ -183,10 +57,10 @@ int luat_fskv_clear(void) {
 }
 
 int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
-    *using_sz = lfs_fs_size(&fskv->lfs) * LFS_BLOCK_DEVICE_ERASE_SIZE;
+    *using_sz = lfs_fs_size(&sfd_lfs->lfs) * LFS_BLOCK_DEVICE_ERASE_SIZE;
     *total = LFS_BLOCK_DEVICE_TOTOAL_SIZE;
     lfs_dir_t dir = {0};
-    int ret = lfs_dir_open(&fskv->lfs, &dir, "");
+    int ret = lfs_dir_open(&sfd_lfs->lfs, &dir, "");
     if (ret != LFS_ERR_OK) {
         LLOGW("lfs_dir_open ret %d", ret);
         return -1;
@@ -194,7 +68,7 @@ int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
     size_t count = 0;
     struct lfs_info info = {0};
     while (1) {
-        ret = lfs_dir_read(&fskv->lfs, &dir, &info);
+        ret = lfs_dir_read(&sfd_lfs->lfs, &dir, &info);
         if (ret > 0) {
             if (info.type == LFS_TYPE_REG)
                 count ++;
@@ -202,7 +76,7 @@ int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
         else
             break;
     }
-    lfs_dir_close(&fskv->lfs, &dir);
+    lfs_dir_close(&sfd_lfs->lfs, &dir);
     *kv_count = count;
     return 0;
 }

+ 0 - 18
components/fskv/luat_fskv.h

@@ -24,25 +24,7 @@
 
 #include "lfs.h"
 
-#define LFS_BLOCK_DEVICE_READ_SIZE (256)
-#define LFS_BLOCK_DEVICE_PROG_SIZE (256)
-#define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
-#define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
-#define LFS_BLOCK_DEVICE_TOTOAL_SIZE (64 * 1024)
-#define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
 
-#define LUAT_FSKV_MAX_SIZE (4096)
-
-
-typedef struct luat_fskv
-{
-    char read_buffer[LFS_BLOCK_DEVICE_READ_SIZE];
-    char prog_buffer[LFS_BLOCK_DEVICE_PROG_SIZE];
-    // char cache_buffer[LFS_BLOCK_DEVICE_CACHE_SIZE];
-    char lookahead_buffer[LFS_BLOCK_DEVICE_LOOK_AHEAD];
-    lfs_t lfs;
-    struct lfs_config conf;
-}luat_fskv_t;
 
 /**
  * @defgroup luatos_fskv 持久化数据存储接口

+ 28 - 15
components/fskv/luat_lib_fskv.c

@@ -28,25 +28,28 @@ fskv与fdb的实现机制导致的差异
 #include "luat_malloc.h"
 
 #include "luat_fskv.h"
+#include "luat_sfd.h"
 
 #ifndef LUAT_LOG_TAG
 #define LUAT_LOG_TAG "fskv"
 #include "luat_log.h"
 #endif
 
-extern luat_fskv_t* fskv;
+#define LUAT_FSKV_MAX_SIZE (4096)
+
+extern sfd_drv_t* sfd_onchip;
+extern luat_sfd_lfs_t* sfd_lfs;
 
 static char fskv_read_buff[LUAT_FSKV_MAX_SIZE];
 
 /**
 初始化kv数据库
-@api fskv.kvdb_init(name, partition)
+@api fskv.init()
 @string 数据库名,当前仅支持env
 @string FAL分区名,当前仅支持onchip_fdb
 @return boolean 成功返回true,否则返回false
 @usage
--- fdb库基于 flashdb , 再次表示感谢.
-if fskv.kvdb_init("env", "onchip_fdb") then
+if fskv.init() then
     log.info("fdb", "kv数据库初始化成功")
 end
 
@@ -55,13 +58,23 @@ end
 -- 写一个main.lua, 执行 fskv.kvdb_init 后 执行 fskv.clear() 即可全清fdb数据.
  */
 static int l_fskvdb_init(lua_State *L) {
-    if (fskv == NULL) {
-        int ret = luat_fskv_init();
-        lua_pushboolean(L, ret == 0 ? 1 : 0);
-    }
-    else {
-        lua_pushboolean(L, 1);
+    if (sfd_lfs == NULL) {
+        if (sfd_onchip == NULL) {
+            luat_sfd_onchip_init();
+        }
+        if (sfd_onchip == NULL) {
+            LLOGE("sfd-onchip init failed");
+            return 0;
+        }
+        if (sfd_lfs == NULL) {
+            luat_sfd_lfs_init(sfd_onchip);
+        }
+        if (sfd_lfs == NULL) {
+            LLOGE("sfd-onchip lfs int failed");
+            return 0;
+        }
     }
+    lua_pushboolean(L, 1);
     return 1;
 }
 
@@ -78,7 +91,7 @@ if fskv.kvdb_init("env", "onchip_fdb") then
 end
  */
 static int l_fskv_set(lua_State *L) {
-    if (fskv == 0) {
+    if (sfd_lfs == 0) {
         LLOGE("call fskv.init() first!!!");
         return 0;
     }
@@ -192,7 +205,7 @@ if fskv.init() then
 end
  */
 static int l_fskv_get(lua_State *L) {
-    if (fskv == NULL) {
+    if (sfd_lfs == NULL) {
         LLOGE("call fskv.init() first!!!");
         return 0;
     }
@@ -262,7 +275,7 @@ if fskv.kvdb_init("env", "onchip_fdb") then
 end
  */
 static int l_fskv_del(lua_State *L) {
-    if (fskv == NULL) {
+    if (sfd_lfs == NULL) {
         LLOGE("call fskv.init() first!!!");
         return 0;
     }
@@ -285,7 +298,7 @@ static int l_fskv_del(lua_State *L) {
 fskv.kv_clr()
  */
 static int l_fskv_clr(lua_State *L) {
-    if (fskv == NULL) {
+    if (sfd_lfs == NULL) {
         LLOGE("call fskv.init() first!!!");
         return 0;
     }
@@ -376,7 +389,7 @@ static int l_fskv_stat(lua_State *L) {
     size_t using_sz = 0;
     size_t max_sz = 0;
     size_t kv_count = 0;
-    if (fskv == 0) {
+    if (sfd_lfs == 0) {
         LLOGE("call fskv.init() first!!!");
         return 0;
     }

+ 15 - 1
components/sfd/luat_lib_sfd.c

@@ -9,11 +9,12 @@
 #include "luat_spi.h"
 #include "luat_sfd.h"
 
-#define LUAT_LOG_SDF
+#define LUAT_LOG_TAG "sfd"
 #include "luat_log.h"
 
 extern const sdf_opts_t sfd_w25q_opts;
 extern const sdf_opts_t sfd_mem_opts;
+extern const sdf_opts_t sfd_onchip_opts;
 
 /*
 初始化spi flash
@@ -47,6 +48,7 @@ static int l_sfd_init(lua_State *L) {
         if (re == 0) {
             return 1;
         }
+        return 0;
     }
     if (!strcmp("zbuff", type)) {
         sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
@@ -60,6 +62,18 @@ static int l_sfd_init(lua_State *L) {
         if (re == 0) {
             return 1;
         }
+        return 0;
+    }
+    if (!strcmp("onchip", type)) {
+        sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
+        memset(drv, 0, sizeof(sfd_drv_t));
+        drv->type = 3;
+        drv->opts = &sfd_onchip_opts;
+        int re = drv->opts->initialize(drv);
+        if (re == 0) {
+            return 1;
+        }
+        return 0;
     }
     return 0;
 }

+ 38 - 0
components/sfd/luat_sfd.c

@@ -0,0 +1,38 @@
+
+#include "luat_base.h"
+
+#include "luat_sfd.h"
+#include "luat_malloc.h"
+
+#define LUAT_LOG_TAG "sfd"
+#include "luat_log.h"
+
+int luat_sfd_status (sfd_drv_t* drv) {
+    if (drv == NULL)
+        return -1;
+    return drv->opts->status(drv->userdata);
+}
+
+int luat_sfd_read (sfd_drv_t* drv, char* buff, size_t offset, size_t len) {
+    if (drv == NULL)
+        return -1;
+    return drv->opts->read(drv->userdata, buff, offset, len);
+}
+
+int luat_sfd_write (sfd_drv_t* drv, const char* buff, size_t offset, size_t len) {
+    if (drv == NULL)
+        return -1;
+    return drv->opts->write(drv->userdata, buff, offset, len);
+}
+
+int luat_sfd_erase (sfd_drv_t* drv, size_t offset, size_t len) {
+    if (drv == NULL)
+        return -1;
+    return drv->opts->erase(drv->userdata, offset, len);
+}
+
+int luat_sfd_ioctl (sfd_drv_t* drv, size_t cmd, void* buff) {
+    if (drv == NULL)
+        return -1;
+    return drv->opts->ioctl(drv->userdata, cmd, buff);
+}

+ 109 - 0
components/sfd/luat_sfd_lfs.c

@@ -0,0 +1,109 @@
+
+#include "luat_base.h"
+
+#include "luat_sfd.h"
+#include "luat_malloc.h"
+
+#define LUAT_LOG_TAG "lfs"
+#include "luat_log.h"
+
+luat_sfd_lfs_t* sfd_lfs;
+
+// Read a block
+static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, void *buffer, lfs_size_t size) {
+    sfd_drv_t* drv = cfg->context;
+    int ret = luat_sfd_read(drv, buffer, block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
+    // LLOGD("sfd read %d %d %d %d", block, off, size, ret);
+    if (ret >= 0) {
+        // LLOGD("block_device_read return LFS_ERR_OK");
+        return LFS_ERR_OK;
+    }
+    // LLOGD("block_device_read return LFS_ERR_IO");
+    return LFS_ERR_IO;
+}
+
+// Program a block
+//
+// The block must have previously been erased.
+static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
+        lfs_off_t off, const void *buffer, lfs_size_t size) {
+    sfd_drv_t* drv = cfg->context;
+    int ret = luat_sfd_write(drv, buffer, block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
+    // LLOGD("sfd write %d %d %d %d", block, off, size, ret);
+    if (ret >= 0) {
+        // LLOGD("block_device_prog return LFS_ERR_OK");
+        return LFS_ERR_OK;
+    }
+    // LLOGD("block_device_prog return LFS_ERR_IO");
+    return LFS_ERR_IO;
+}
+
+// Erase a block
+//
+// A block must be erased before being programmed. The
+// state of an erased block is undefined.
+static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block) {
+    sfd_drv_t* drv = cfg->context;
+    int ret = luat_sfd_erase(drv, block * LFS_BLOCK_DEVICE_ERASE_SIZE, LFS_BLOCK_DEVICE_ERASE_SIZE);
+    // LLOGD("sfd erase %d %d", block, ret);
+    (void)ret;
+    return 0;
+}
+
+// Sync the block device
+static int block_device_sync(const struct lfs_config *cfg) {
+    return 0;
+}
+
+int luat_sfd_lfs_init(sfd_drv_t *drv) {
+    int ret = 0;
+    if (sfd_lfs == NULL) {
+        sfd_lfs = luat_heap_malloc(sizeof(luat_sfd_lfs_t));
+        if (sfd_lfs == NULL) {
+            LLOGE("out of memory when malloc sfd_lfs");
+            return -1;
+        }
+        memset(sfd_lfs, 0, sizeof(luat_sfd_lfs_t));
+        sfd_lfs->conf.read = block_device_read;
+        sfd_lfs->conf.prog = block_device_prog;
+        sfd_lfs->conf.erase = block_device_erase;
+        sfd_lfs->conf.sync = block_device_sync;
+        sfd_lfs->conf.attr_max = 0;
+        sfd_lfs->conf.file_max = 4096;
+        sfd_lfs->conf.block_count = (LFS_BLOCK_DEVICE_TOTOAL_SIZE) / LFS_BLOCK_DEVICE_ERASE_SIZE;
+        sfd_lfs->conf.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
+        sfd_lfs->conf.block_cycles = 200;
+        sfd_lfs->conf.name_max = 63;
+        sfd_lfs->conf.read_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        sfd_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        sfd_lfs->conf.prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
+        sfd_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        sfd_lfs->conf.lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
+        sfd_lfs->conf.lookahead_buffer = sfd_lfs->lookahead_buffer;
+        sfd_lfs->conf.prog_buffer = sfd_lfs->prog_buffer;
+        sfd_lfs->conf.read_buffer = sfd_lfs->read_buffer;
+        sfd_lfs->conf.context = drv;
+
+        ret = lfs_mount(&sfd_lfs->lfs, &sfd_lfs->conf);
+        if (ret != LFS_ERR_OK) {
+            LLOGI("sfd_lfs mount ret %d, exec auto-format", ret);
+            ret = lfs_format(&sfd_lfs->lfs, &sfd_lfs->conf);
+            if (ret != LFS_ERR_OK) {
+                luat_heap_free(sfd_lfs);
+                sfd_lfs = NULL;
+                LLOGE("sfd_lfs auto-format ret %d", ret);
+                return ret;
+            }
+            ret = lfs_mount(&sfd_lfs->lfs, &sfd_lfs->conf);
+            if (ret != LFS_ERR_OK) {
+                luat_heap_free(sfd_lfs);
+                sfd_lfs = NULL;
+                LLOGE("sfd_lfs remount ret %d", ret);
+                return ret;
+            }
+        }
+        LLOGD("init ok");
+    }
+    return 0;
+}

+ 26 - 107
components/sfd/luat_sfd_onchip.c

@@ -4,18 +4,6 @@
 #include "luat_sfd.h"
 #include "luat_malloc.h"
 
-#include "lfs.h"
-
-#ifdef LUAT_SFD_ONCHIP
-#if LUAT_SFD_ONCHIP
-
-int sfd_onchip_init (void* userdata);
-int sfd_onchip_status (void* userdata);
-int sfd_onchip_read (void* userdata, char* buff, size_t offset, size_t len);
-int sfd_onchip_write (void* userdata, const char* buff, size_t offset, size_t len);
-int sfd_onchip_erase (void* userdata, size_t offset, size_t len);
-int sfd_onchip_ioctl (void* userdata, size_t cmd, void* buff);
-
 const sdf_opts_t sfd_onchip_opts = {
     .initialize = sfd_onchip_init,
     .status = sfd_onchip_status,
@@ -25,101 +13,32 @@ const sdf_opts_t sfd_onchip_opts = {
     .ioctl = sfd_onchip_ioctl,
 };
 
+sfd_drv_t* sfd_onchip;
 
-
-#include "lfs.h"
-#define LFS_BLOCK_SIZE (4096)
-#define LFS_BLOCK_DEVICE_READ_SIZE (256)
-#define LFS_BLOCK_DEVICE_PROG_SIZE (256)
-#define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
-#define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
-//#define LFS_BLOCK_DEVICE_TOTOAL_SIZE (FLASH_FS_REGION_SIZE)
-#define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
-
-// Read a block
-static int block_device_read(const struct lfs_config *cfg, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
-    sfd_onchip_t* onchip = (sfd_onchip_t*)cfg->context;
-    sfd_onchip_read(onchip, buffer, block * LFS_BLOCK_SIZE + off, size);
-    return LFS_ERR_OK;
-}
-
-static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
-    sfd_onchip_t* onchip = (sfd_onchip_t*)cfg->context;
-    sfd_onchip_write(onchip, buffer, block * LFS_BLOCK_SIZE + off, size);
-    return LFS_ERR_OK;
-}
-
-static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block) {
-    sfd_onchip_t* onchip = (sfd_onchip_t*)cfg->context;
-    sfd_onchip_erase(onchip, block * LFS_BLOCK_SIZE, LFS_BLOCK_SIZE);
-    return LFS_ERR_OK;
-}
-
-static int block_device_sync(const struct lfs_config *cfg) {
-    sfd_onchip_t* onchip = (sfd_onchip_t*)cfg->context;
-    sfd_onchip_ioctl(onchip, 0x05, NULL);
-    return LFS_ERR_OK;
-}
-
-typedef struct LFS2 {
-    lfs_t lfs;
-    struct lfs_config cfg;
-    uint8_t read_buffer[LFS_BLOCK_DEVICE_READ_SIZE];
-    uint8_t prog_buffer[LFS_BLOCK_DEVICE_PROG_SIZE];
-    uint8_t lookahead_buffer[LFS_BLOCK_DEVICE_LOOK_AHEAD];
-}LFS2_t;
-
-
-lfs_t* onchip_lfs_sfd(sfd_onchip_t* onchip) {
-    LFS2_t *_lfs = luat_heap_malloc(sizeof(LFS2_t));
-    if (_lfs == NULL)
-        return NULL;
-    lfs_t *lfs = &_lfs->lfs;
-    struct lfs_config *lfs_cfg = &_lfs->cfg;
-
-    lfs_cfg->context = onchip,
-    // block device operations
-    lfs_cfg->read = block_device_read;
-    lfs_cfg->prog = block_device_prog;
-    lfs_cfg->erase = block_device_erase;
-    lfs_cfg->sync = block_device_sync;
-
-    // block device configuration
-    lfs_cfg->read_size = LFS_BLOCK_DEVICE_READ_SIZE;
-    lfs_cfg->prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
-    lfs_cfg->block_size = LFS_BLOCK_SIZE;
-    lfs_cfg->block_count = onchip->block_count;
-    lfs_cfg->block_cycles = 200;
-    lfs_cfg->cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
-    lfs_cfg->lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
-
-    lfs_cfg->read_buffer = _lfs->read_buffer;
-    lfs_cfg->prog_buffer = _lfs->prog_buffer;
-    lfs_cfg->lookahead_buffer = _lfs->lookahead_buffer;
-    lfs_cfg->name_max = 63;
-    lfs_cfg->file_max = 0;
-    lfs_cfg->attr_max = 0;
-
-    // ------
-    int err = lfs_mount(lfs, lfs_cfg);
-    LLOGD("lfs_mount %d",err);
-    if (err)
-    {
-        err = lfs_format(lfs, lfs_cfg);
-        LLOGD("lfs_format %d",err);
-        if(err)
-            goto fail;
-        err = lfs_mount(lfs, lfs_cfg);
-        LLOGD("lfs_mount %d",err);
-        if(err)
-            goto fail;
+int luat_sfd_onchip_init(void) {
+    if (sfd_onchip != NULL) {
+        return 0;
+    }
+    sfd_onchip = luat_heap_malloc(sizeof(sfd_drv_t));
+    if (sfd_onchip == NULL) {
+        return -1;
+    }
+    sfd_onchip_t * onchip = luat_heap_malloc(sizeof(sfd_onchip_t));
+    if (onchip == NULL) {
+        luat_heap_free(sfd_onchip);
+        sfd_onchip = NULL;
+        return -2;
     }
-    return lfs;
-fail :
-    luat_heap_free(_lfs);
-    return NULL;
-    //------
+    memset(sfd_onchip, 0, sizeof(sfd_drv_t));
+    sfd_onchip->opts = &sfd_onchip_opts;
+    sfd_onchip->type = 2;
+    sfd_onchip->userdata = onchip;
+    int ret = sfd_onchip_init(onchip);
+    if (ret != NULL) {
+        luat_heap_free(onchip);
+        luat_heap_free(sfd_onchip);
+        sfd_onchip = NULL;
+        return -3;
+    }
+    return ret;
 }
-
-#endif
-#endif