fix: libfota2的URL应该只合成一次
[LuatOS.git] / components / fskv / luat_fskv.c
blob745122a576d7e3cbfe556a24c536ed695683dafd
1 #ifndef __LUATOS__
2 #include "luat_base.h"
3 #include "luat_fskv.h"
4 #include "lfs.h"
5 #include "luat_flash.h"
7 #define LUAT_LOG_TAG "fskv"
8 #include "luat_log.h"
10 #define LFS_BLOCK_DEVICE_READ_SIZE (256)
11 #define LFS_BLOCK_DEVICE_PROG_SIZE (256)
12 #define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
13 #define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
14 //#define LFS_BLOCK_DEVICE_TOTOAL_SIZE (64 * 1024)
15 #define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
18 typedef struct luat_kvfs_lfs
20 char read_buffer[LFS_BLOCK_DEVICE_READ_SIZE];
21 char prog_buffer[LFS_BLOCK_DEVICE_PROG_SIZE];
22 // char cache_buffer[LFS_BLOCK_DEVICE_CACHE_SIZE];
23 char lookahead_buffer[LFS_BLOCK_DEVICE_LOOK_AHEAD];
24 lfs_t lfs;
25 uint32_t fskv_address;
26 uint32_t total_len;
27 struct lfs_config conf;
28 }luat_kvfs_lfs_t;
30 static luat_kvfs_lfs_t* fskv_lfs;
32 // Read a block
33 static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
34 lfs_off_t off, void *buffer, lfs_size_t size) {
35 luat_flash_read(buffer, fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
36 return LFS_ERR_OK;
39 // Program a block
41 // The block must have previously been erased.
42 static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
43 lfs_off_t off, const void *buffer, lfs_size_t size) {
45 int ret = luat_flash_write((char *)buffer, fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE + off, size);
46 if (ret >= 0) {
47 // LLOGD("block_device_prog return LFS_ERR_OK");
48 return LFS_ERR_OK;
50 // LLOGD("block_device_prog return LFS_ERR_IO");
51 return LFS_ERR_IO;
54 // Erase a block
56 // A block must be erased before being programmed. The
57 // state of an erased block is undefined.
58 static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block) {
59 luat_flash_erase(fskv_lfs->fskv_address + block * LFS_BLOCK_DEVICE_ERASE_SIZE, LFS_BLOCK_DEVICE_ERASE_SIZE);
60 return 0;
63 // Sync the block device
64 static int block_device_sync(const struct lfs_config *cfg) {
65 return 0;
68 static int luat_fskv_lfs_init(uint32_t fskv_address, uint32_t total_len) {
69 int ret = 0;
70 if (fskv_lfs == NULL) {
71 fskv_lfs = malloc(sizeof(luat_kvfs_lfs_t));
72 if (fskv_lfs == NULL) {
73 LLOGE("out of memory when malloc fskv_lfs");
74 return -1;
76 memset(fskv_lfs, 0, sizeof(luat_kvfs_lfs_t));
77 fskv_lfs->fskv_address = fskv_address;
78 fskv_lfs->total_len = total_len;
79 fskv_lfs->conf.read = block_device_read;
80 fskv_lfs->conf.prog = block_device_prog;
81 fskv_lfs->conf.erase = block_device_erase;
82 fskv_lfs->conf.sync = block_device_sync;
83 fskv_lfs->conf.attr_max = 0;
84 fskv_lfs->conf.file_max = 4096;
85 fskv_lfs->conf.block_count = (total_len) / LFS_BLOCK_DEVICE_ERASE_SIZE;
86 fskv_lfs->conf.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
87 fskv_lfs->conf.block_cycles = 200;
88 fskv_lfs->conf.name_max = 63;
89 fskv_lfs->conf.read_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
90 fskv_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
91 fskv_lfs->conf.prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
92 fskv_lfs->conf.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
93 fskv_lfs->conf.lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
94 fskv_lfs->conf.lookahead_buffer = fskv_lfs->lookahead_buffer;
95 fskv_lfs->conf.prog_buffer = fskv_lfs->prog_buffer;
96 fskv_lfs->conf.read_buffer = fskv_lfs->read_buffer;
98 ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
99 if (ret != LFS_ERR_OK) {
100 ret = lfs_format(&fskv_lfs->lfs, &fskv_lfs->conf);
101 if (ret != LFS_ERR_OK) {
102 free(fskv_lfs);
103 fskv_lfs = NULL;
104 LLOGE("fskv_lfs auto-format ret %d", ret);
105 return ret;
107 ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
108 if (ret != LFS_ERR_OK) {
109 free(fskv_lfs);
110 fskv_lfs = NULL;
111 LLOGE("fskv_lfs remount ret %d", ret);
112 return ret;
115 LLOGE("init ok");
117 return 0;
121 int luat_fskv_del(const char* key) {
122 lfs_remove(&fskv_lfs->lfs, key);
123 return 0;
126 int luat_fskv_set(const char* key, void* data, size_t len) {
127 lfs_file_t fd = {0};
128 int ret = 0;
129 ret = lfs_file_open(&fskv_lfs->lfs, &fd, key, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC);
130 if (ret != LFS_ERR_OK) {
131 return -1;
133 ret = lfs_file_write(&fskv_lfs->lfs, &fd, data, len);
134 lfs_file_close(&fskv_lfs->lfs, &fd);
135 return ret;
138 int luat_fskv_get(const char* key, void* data, size_t len) {
139 lfs_file_t fd = {0};
140 int ret = 0;
141 ret = lfs_file_open(&fskv_lfs->lfs, &fd, key, LFS_O_RDONLY);
142 if (ret != LFS_ERR_OK) {
143 return 0;
145 ret = lfs_file_read(&fskv_lfs->lfs, &fd, data, len);
146 lfs_file_close(&fskv_lfs->lfs, &fd);
147 return ret > 0 ? ret : 0;
150 int luat_fskv_clear(void) {
151 int ret = 0;
152 ret = lfs_format(&fskv_lfs->lfs, &fskv_lfs->conf);
153 if (ret != LFS_ERR_OK) {
154 LLOGE("fskv clear ret %d", ret);
155 return ret;
157 ret = lfs_mount(&fskv_lfs->lfs, &fskv_lfs->conf);
158 if (ret != LFS_ERR_OK) {
159 LLOGE("fskv reinit ret %d", ret);
160 return ret;
162 return 0;
165 int luat_fskv_stat(size_t *using_sz, size_t *total, size_t *kv_count) {
166 *using_sz = lfs_fs_size(&fskv_lfs->lfs) * LFS_BLOCK_DEVICE_ERASE_SIZE;
167 *total = fskv_lfs->total_len;
168 lfs_dir_t dir = {0};
169 int ret = lfs_dir_open(&fskv_lfs->lfs, &dir, "");
170 if (ret != LFS_ERR_OK) {
171 LLOGE("lfs_dir_open ret %d", ret);
172 return -1;
174 size_t count = 0;
175 struct lfs_info info = {0};
176 while (1) {
177 ret = lfs_dir_read(&fskv_lfs->lfs, &dir, &info);
178 if (ret > 0) {
179 if (info.type == LFS_TYPE_REG)
180 count ++;
182 else
183 break;
185 lfs_dir_close(&fskv_lfs->lfs, &dir);
186 *kv_count = count;
187 return 0;
190 int luat_fskv_next(char* buff, size_t offset) {
191 lfs_dir_t dir = {0};
192 struct lfs_info info = {0};
193 // offset要+2, 因为前2个值是"."和".."两个dir
194 offset += 2;
195 int ret = lfs_dir_open(&fskv_lfs->lfs, &dir, "");
196 if (ret < 0) {
197 LLOGE("lfs_dir_open ret %d", ret);
198 return -1;
200 ret = lfs_dir_seek(&fskv_lfs->lfs, &dir, offset);
201 if (ret < 0) {
202 lfs_dir_close(&fskv_lfs->lfs, &dir);
203 return -2;
205 ret = lfs_dir_read(&fskv_lfs->lfs, &dir, &info);
206 if (ret <= 0) {
207 lfs_dir_close(&fskv_lfs->lfs, &dir);
208 return -3;
210 memcpy(buff, info.name, strlen(info.name) + 1);
211 lfs_dir_close(&fskv_lfs->lfs, &dir);
212 return 0;
215 int luat_fskv_init(void)
217 if (fskv_lfs == NULL) {
218 if (fskv_lfs == NULL) {
219 size_t len = 0;
220 size_t start_address = luat_flash_get_fskv_addr(&len);
221 if (start_address == 0) {
222 LLOGE("fskv init failed");
223 return -1;
225 LLOGE("fskv addr and len %d %d", start_address, len);
226 luat_fskv_lfs_init(start_address, len);
228 if (fskv_lfs == NULL) {
229 LLOGE("fskv init failed");
230 return -1;
233 return 0;
236 #endif