Explorar o código

add: lfs fskv

doudou %!s(int64=2) %!d(string=hai) anos
pai
achega
e4a61f4795
Modificáronse 3 ficheiros con 287 adicións e 46 borrados
  1. 155 46
      components/fskv/luat_fskv.c
  2. 125 0
      components/fskv/luat_fskv_sfd.c
  3. 7 0
      luat/include/luat_flash.h

+ 155 - 46
components/fskv/luat_fskv.c

@@ -1,54 +1,159 @@
 #include "luat_base.h"
 #include "luat_fskv.h"
-#include "luat_malloc.h"
-#include "luat_msgbus.h"
-#include "luat_sfd.h"
+#include "lfs.h"
+#include "luat_flash.h"
 
 #define LUAT_LOG_TAG "fskv"
 #include "luat_log.h"
 
-#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)
+
+
+typedef struct luat_kvfs_lfs
+{
+    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;
+    uint32_t fskv_address;
+    uint32_t total_len;
+    struct lfs_config conf;
+}luat_kvfs_lfs_t;
+
+static luat_kvfs_lfs_t* fskv_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) {
+    luat_flash_read(buffer, fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
+    return LFS_ERR_OK;
+}
+
+// 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 = luat_flash_write((char *)buffer, fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
+    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) {
+    luat_flash_erase(fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE, LFS_BLOCK_DEVICE_ERASE_SIZE);
+    return 0;
+}
+
+// Sync the block device
+static int block_device_sync(const struct lfs_config *cfg) {
+    return 0;
+}
+
+static int luat_fskv_lfs_init(uint32_t fskv_address, uint32_t total_len) {
+    int ret = 0;
+    if (fskv_lfs == NULL) {
+        fskv_lfs = malloc(sizeof(luat_kvfs_lfs_t));
+        if (fskv_lfs == NULL) {
+            LLOGE("out of memory when malloc fskv_lfs");
+            return -1;
+        }
+        memset(fskv_lfs, 0, sizeof(luat_kvfs_lfs_t));
+        fskv_lfs->fskv_address = fskv_address;
+        fskv_lfs->total_len = total_len;
+        fskv_lfs->conf.read = block_device_read;
+        fskv_lfs->conf.prog = block_device_prog;
+        fskv_lfs->conf.erase = block_device_erase;
+        fskv_lfs->conf.sync = block_device_sync;
+        fskv_lfs->conf.attr_max = 0;
+        fskv_lfs->conf.file_max = 4096;
+        fskv_lfs->conf.block_count = (total_len) / LFS_BLOCK_DEVICE_ERASE_SIZE;
+        fskv_lfs->conf.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
+        fskv_lfs->conf.block_cycles = 200;
+        fskv_lfs->conf.name_max = 63;
+        fskv_lfs->conf.read_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        fskv_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        fskv_lfs->conf.prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
+        fskv_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
+        fskv_lfs->conf.lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
+        fskv_lfs->conf.lookahead_buffer = fskv_lfs->lookahead_buffer;
+        fskv_lfs->conf.prog_buffer = fskv_lfs->prog_buffer;
+        fskv_lfs->conf.read_buffer = fskv_lfs->read_buffer;
+
+        ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
+        if (ret != LFS_ERR_OK) {
+            ret = lfs_format(&fskv_lfs->lfs, &fskv_lfs->conf);
+            if (ret != LFS_ERR_OK) {
+                free(fskv_lfs);
+                fskv_lfs = NULL;
+                LLOGE("fskv_lfs auto-format ret %d", ret);
+                return ret;
+            }
+            ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
+            if (ret != LFS_ERR_OK) {
+            	free(fskv_lfs);
+                fskv_lfs = NULL;
+                LLOGE("fskv_lfs remount ret %d", ret);
+                return ret;
+            }
+        }
+        LLOGE("init ok");
+    }
+    return 0;
+}
 
-// TODO 应该对接vfs, 而非直接对接lfs
-extern luat_sfd_lfs_t* sfd_lfs;
 
 int luat_fskv_del(const char* key) {
-    lfs_remove(&sfd_lfs->lfs, key);
+    lfs_remove(&fskv_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(&sfd_lfs->lfs, &fd, key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
+    ret = lfs_file_open(&fskv_lfs->lfs, &fd, key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
     if (ret != LFS_ERR_OK) {
         return -1;
     }
-    ret = lfs_file_write(&sfd_lfs->lfs, &fd, data, len);
-    lfs_file_close(&sfd_lfs->lfs, &fd);
+    ret = lfs_file_write(&fskv_lfs->lfs, &fd, data, len);
+    lfs_file_close(&fskv_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(&sfd_lfs->lfs, &fd, key, LFS_O_RDONLY);
+    ret = lfs_file_open(&fskv_lfs->lfs, &fd, key, LFS_O_RDONLY);
     if (ret != LFS_ERR_OK) {
         return 0;
     }
-    ret = lfs_file_read(&sfd_lfs->lfs, &fd, data, len);
-    lfs_file_close(&sfd_lfs->lfs, &fd);
+    ret = lfs_file_read(&fskv_lfs->lfs, &fd, data, len);
+    lfs_file_close(&fskv_lfs->lfs, &fd);
     return ret > 0 ? ret : 0;
 }
 
 int luat_fskv_clear(void) {
     int ret = 0;
-    ret = lfs_format(&sfd_lfs->lfs, &sfd_lfs->conf);
+    ret = lfs_format(&fskv_lfs->lfs, &fskv_lfs->conf);
     if (ret != LFS_ERR_OK) {
         LLOGE("fskv clear ret %d", ret);
         return ret;
     }
-    ret = lfs_mount(&sfd_lfs->lfs, &sfd_lfs->conf);
+    ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
     if (ret != LFS_ERR_OK) {
         LLOGE("fskv reinit ret %d", ret);
         return ret;
@@ -57,18 +162,18 @@ 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(&sfd_lfs->lfs) * LFS_BLOCK_DEVICE_ERASE_SIZE;
-    *total = LFS_BLOCK_DEVICE_TOTOAL_SIZE;
+    *using_sz = lfs_fs_size(&fskv_lfs->lfs) * LFS_BLOCK_DEVICE_ERASE_SIZE;
+    *total = fskv_lfs->total_len;
     lfs_dir_t dir = {0};
-    int ret = lfs_dir_open(&sfd_lfs->lfs, &dir, "");
+    int ret = lfs_dir_open(&fskv_lfs->lfs, &dir, "");
     if (ret != LFS_ERR_OK) {
-        LLOGW("lfs_dir_open ret %d", ret);
+        LLOGE("lfs_dir_open ret %d", ret);
         return -1;
     }
     size_t count = 0;
     struct lfs_info info = {0};
     while (1) {
-        ret = lfs_dir_read(&sfd_lfs->lfs, &dir, &info);
+        ret = lfs_dir_read(&fskv_lfs->lfs, &dir, &info);
         if (ret > 0) {
             if (info.type == LFS_TYPE_REG)
                 count ++;
@@ -76,50 +181,54 @@ int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
         else
             break;
     }
-    lfs_dir_close(&sfd_lfs->lfs, &dir);
+    lfs_dir_close(&fskv_lfs->lfs, &dir);
     *kv_count = count;
     return 0;
 }
 
-int luat_fskv_size(const char* key, char buff[4]) {
-    lfs_file_t fd = {0};
-    int ret = 0;
-    ret = lfs_file_open(&sfd_lfs->lfs, &fd, key, LFS_O_RDONLY);
-    if (ret != LFS_ERR_OK) {
-        return 0;
-    }
-    ret = lfs_file_size(&sfd_lfs->lfs, &fd);
-    if (ret > 1 && ret < 256) {
-        int ret2 = lfs_file_read(&sfd_lfs->lfs, &fd, buff, ret);
-        if (ret2 != ret) {
-            ret = -2; // 读取失败,肯定有问题
-        }
-    }
-    lfs_file_close(&sfd_lfs->lfs, &fd);
-    return ret;
-}
-
 int luat_fskv_next(char* buff, size_t offset) {
     lfs_dir_t dir = {0};
     struct lfs_info info = {0};
     // offset要+2, 因为前2个值是"."和".."两个dir
     offset += 2;
-    int ret = lfs_dir_open(&sfd_lfs->lfs, &dir, "");
+    int ret = lfs_dir_open(&fskv_lfs->lfs, &dir, "");
     if (ret < 0) {
-        LLOGW("lfs_dir_open ret %d", ret);
+        LLOGE("lfs_dir_open ret %d", ret);
         return -1;
     }
-    ret = lfs_dir_seek(&sfd_lfs->lfs, &dir, offset);
+    ret = lfs_dir_seek(&fskv_lfs->lfs, &dir, offset);
     if (ret < 0) {
-        lfs_dir_close(&sfd_lfs->lfs, &dir);
+        lfs_dir_close(&fskv_lfs->lfs, &dir);
         return -2;
     }
-    ret = lfs_dir_read(&sfd_lfs->lfs, &dir, &info);
+    ret = lfs_dir_read(&fskv_lfs->lfs, &dir, &info);
     if (ret <= 0) {
-        lfs_dir_close(&sfd_lfs->lfs, &dir);
+        lfs_dir_close(&fskv_lfs->lfs, &dir);
         return -3;
     }
     memcpy(buff, info.name, strlen(info.name) + 1);
-    lfs_dir_close(&sfd_lfs->lfs, &dir);
+    lfs_dir_close(&fskv_lfs->lfs, &dir);
+    return 0;
+}
+
+int luat_fskv_init(void)
+{
+    if (fskv_lfs == NULL) {
+        if (fskv_lfs == NULL) {
+            size_t len = 0;
+            size_t start_address = luat_flash_get_fskv_addr(&len);
+            if (start_address == 0) {
+                LLOGE("fskv init failed");
+                return -1;
+            }
+            LLOGE("fskv addr and len %d %d", start_address, len);
+            luat_fskv_lfs_init(start_address, len);
+        }
+        if (fskv_lfs == NULL) {
+            LLOGE("fskv init failed");
+            return -1;
+        }
+    }
     return 0;
+
 }

+ 125 - 0
components/fskv/luat_fskv_sfd.c

@@ -0,0 +1,125 @@
+#include "luat_base.h"
+#include "luat_fskv.h"
+#include "luat_malloc.h"
+#include "luat_msgbus.h"
+#include "luat_sfd.h"
+
+#define LUAT_LOG_TAG "fskv_sfd"
+#include "luat_log.h"
+
+#include "lfs.h"
+
+// TODO 应该对接vfs, 而非直接对接lfs
+extern luat_sfd_lfs_t* sfd_lfs;
+
+int luat_fskv_del(const char* 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(&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(&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(&sfd_lfs->lfs, &fd, key, LFS_O_RDONLY);
+    if (ret != LFS_ERR_OK) {
+        return 0;
+    }
+    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(&sfd_lfs->lfs, &sfd_lfs->conf);
+    if (ret != LFS_ERR_OK) {
+        LLOGE("fskv clear ret %d", ret);
+        return ret;
+    }
+    ret = lfs_mount(&sfd_lfs->lfs, &sfd_lfs->conf);
+    if (ret != LFS_ERR_OK) {
+        LLOGE("fskv reinit ret %d", ret);
+        return ret;
+    }
+    return 0;
+}
+
+int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
+    *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(&sfd_lfs->lfs, &dir, "");
+    if (ret != LFS_ERR_OK) {
+        LLOGW("lfs_dir_open ret %d", ret);
+        return -1;
+    }
+    size_t count = 0;
+    struct lfs_info info = {0};
+    while (1) {
+        ret = lfs_dir_read(&sfd_lfs->lfs, &dir, &info);
+        if (ret > 0) {
+            if (info.type == LFS_TYPE_REG)
+                count ++;
+        }
+        else
+            break;
+    }
+    lfs_dir_close(&sfd_lfs->lfs, &dir);
+    *kv_count = count;
+    return 0;
+}
+
+int luat_fskv_size(const char* key, char buff[4]) {
+    lfs_file_t fd = {0};
+    int ret = 0;
+    ret = lfs_file_open(&sfd_lfs->lfs, &fd, key, LFS_O_RDONLY);
+    if (ret != LFS_ERR_OK) {
+        return 0;
+    }
+    ret = lfs_file_size(&sfd_lfs->lfs, &fd);
+    if (ret > 1 && ret < 256) {
+        int ret2 = lfs_file_read(&sfd_lfs->lfs, &fd, buff, ret);
+        if (ret2 != ret) {
+            ret = -2; // 读取失败,肯定有问题
+        }
+    }
+    lfs_file_close(&sfd_lfs->lfs, &fd);
+    return ret;
+}
+
+int luat_fskv_next(char* buff, size_t offset) {
+    lfs_dir_t dir = {0};
+    struct lfs_info info = {0};
+    // offset要+2, 因为前2个值是"."和".."两个dir
+    offset += 2;
+    int ret = lfs_dir_open(&sfd_lfs->lfs, &dir, "");
+    if (ret < 0) {
+        LLOGW("lfs_dir_open ret %d", ret);
+        return -1;
+    }
+    ret = lfs_dir_seek(&sfd_lfs->lfs, &dir, offset);
+    if (ret < 0) {
+        lfs_dir_close(&sfd_lfs->lfs, &dir);
+        return -2;
+    }
+    ret = lfs_dir_read(&sfd_lfs->lfs, &dir, &info);
+    if (ret <= 0) {
+        lfs_dir_close(&sfd_lfs->lfs, &dir);
+        return -3;
+    }
+    memcpy(buff, info.name, strlen(info.name) + 1);
+    lfs_dir_close(&sfd_lfs->lfs, &dir);
+    return 0;
+}

+ 7 - 0
luat/include/luat_flash.h

@@ -37,6 +37,13 @@ int luat_flash_write(char* buff, size_t addr, size_t len);
 int luat_flash_erase(size_t addr, size_t len);
 
 
+/**
+ * @brief 获取kv起始地址与长度
+ * @param len kv大小, 与具体设备相关
+ * @return size_t = 0错误 !=0 正常
+ */
+size_t luat_flash_get_fskv_addr(size_t *len);
+
 /**
  * @}
  */