5 #include "luat_flash.h"
7 #define LUAT_LOG_TAG "fskv"
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
];
25 uint32_t fskv_address
;
27 struct lfs_config conf
;
30 static luat_kvfs_lfs_t
* fskv_lfs
;
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
);
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
);
47 // LLOGD("block_device_prog return LFS_ERR_OK");
50 // LLOGD("block_device_prog return LFS_ERR_IO");
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
);
63 // Sync the block device
64 static int block_device_sync(const struct lfs_config
*cfg
) {
68 static int luat_fskv_lfs_init(uint32_t fskv_address
, uint32_t total_len
) {
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");
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
) {
104 LLOGE("fskv_lfs auto-format ret %d", ret
);
107 ret
= lfs_mount(&fskv_lfs
->lfs
, &fskv_lfs
->conf
);
108 if (ret
!= LFS_ERR_OK
) {
111 LLOGE("fskv_lfs remount ret %d", ret
);
121 int luat_fskv_del(const char* key
) {
122 lfs_remove(&fskv_lfs
->lfs
, key
);
126 int luat_fskv_set(const char* key
, void* data
, size_t len
) {
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
) {
133 ret
= lfs_file_write(&fskv_lfs
->lfs
, &fd
, data
, len
);
134 lfs_file_close(&fskv_lfs
->lfs
, &fd
);
138 int luat_fskv_get(const char* key
, void* data
, size_t len
) {
141 ret
= lfs_file_open(&fskv_lfs
->lfs
, &fd
, key
, LFS_O_RDONLY
);
142 if (ret
!= LFS_ERR_OK
) {
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) {
152 ret
= lfs_format(&fskv_lfs
->lfs
, &fskv_lfs
->conf
);
153 if (ret
!= LFS_ERR_OK
) {
154 LLOGE("fskv clear ret %d", ret
);
157 ret
= lfs_mount(&fskv_lfs
->lfs
, &fskv_lfs
->conf
);
158 if (ret
!= LFS_ERR_OK
) {
159 LLOGE("fskv reinit ret %d", ret
);
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
;
169 int ret
= lfs_dir_open(&fskv_lfs
->lfs
, &dir
, "");
170 if (ret
!= LFS_ERR_OK
) {
171 LLOGE("lfs_dir_open ret %d", ret
);
175 struct lfs_info info
= {0};
177 ret
= lfs_dir_read(&fskv_lfs
->lfs
, &dir
, &info
);
179 if (info
.type
== LFS_TYPE_REG
)
185 lfs_dir_close(&fskv_lfs
->lfs
, &dir
);
190 int luat_fskv_next(char* buff
, size_t offset
) {
192 struct lfs_info info
= {0};
193 // offset要+2, 因为前2个值是"."和".."两个dir
195 int ret
= lfs_dir_open(&fskv_lfs
->lfs
, &dir
, "");
197 LLOGE("lfs_dir_open ret %d", ret
);
200 ret
= lfs_dir_seek(&fskv_lfs
->lfs
, &dir
, offset
);
202 lfs_dir_close(&fskv_lfs
->lfs
, &dir
);
205 ret
= lfs_dir_read(&fskv_lfs
->lfs
, &dir
, &info
);
207 lfs_dir_close(&fskv_lfs
->lfs
, &dir
);
210 memcpy(buff
, info
.name
, strlen(info
.name
) + 1);
211 lfs_dir_close(&fskv_lfs
->lfs
, &dir
);
215 int luat_fskv_init(void)
217 if (fskv_lfs
== NULL
) {
218 if (fskv_lfs
== NULL
) {
220 size_t start_address
= luat_flash_get_fskv_addr(&len
);
221 if (start_address
== 0) {
222 LLOGE("fskv init failed");
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");