为了方便查看,数据库开始地址修改为0x20000,分配4个扇区。
[D/FAL] (fal_flash_init:47) Flash device | stm32_onchip | addr: 0x08000000 | len: 0x00040000 | blk_size: 0x00000800 |initialized finish.
[32;22m[I/FAL] ==================== FAL partition table ====================[0m
[32;22m[I/FAL] | name | flash_dev | offset | length |[0m
[32;22m[I/FAL] -------------------------------------------------------------[0m
[32;22m[I/FAL] | fdb_tsdb1 | stm32_onchip | 0x0001a000 | 0x00002000 |[0m
[32;22m[I/FAL] | fdb_kvdb1 | stm32_onchip | 0x00020000 | 0x00002000 |[0m
[32;22m[I/FAL] =============================================================[0m
[32;22m[I/FAL] Flash Abstraction Layer (V0.5.99) initialize success.[0m
[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:1777) The oldest addr is @0x00000000
[FlashDB][kv][env][fdb_kvdb1] (..\..\..\src\fdb_kvdb.c:1793) KVDB size is 8192 bytes.
[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00000000).
[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00000800).
[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00001000).
[FlashDB][kv][env][fdb_kvdb1] Sector header info is incorrect. Auto format this sector (0x00001800).
[FlashDB][kv][env][fdb_kvdb1] All sector header is incorrect. Set it to default.
[FlashDB] FlashDB V2.1.0 is initialize success.
[FlashDB] You can get the latest version on https://github.com/armink/FlashDB .
/* the flash sector store status flash扇区存储状态*/
enum fdb_sector_store_status {
FDB_SECTOR_STORE_UNUSED,
FDB_SECTOR_STORE_EMPTY,
FDB_SECTOR_STORE_USING,
FDB_SECTOR_STORE_FULL,
#define FDB_SECTOR_STORE_STATUS_NUM 4
};
typedef enum fdb_sector_store_status fdb_sector_store_status_t;
/* the flash sector dirty status flash扇区脏状态*/
enum fdb_sector_dirty_status {
FDB_SECTOR_DIRTY_UNUSED,
FDB_SECTOR_DIRTY_FALSE,
FDB_SECTOR_DIRTY_TRUE,
FDB_SECTOR_DIRTY_GC,
#define FDB_SECTOR_DIRTY_STATUS_NUM 4
};
状态存储格式见fdb_utils.c第99行size_t _fdb_set_status(uint8_t status_table[], size_t status_num, size_t status_index)函数里的注释。
/*
* | write garn | status0 | status1 | status2 | status3 |
* ------------------------------------------------------------------------------------------------------
* | 1bit | 0xFF | 0x7F | 0x3F | 0x1F
* ------------------------------------------------------------------------------------------------------
* | 8bit | 0xFF FF FF | 0x00 FF FF | 0x00 00 FF | 0x00 00 00
* ------------------------------------------------------------------------------------------------------
* | 32bit | 0xFFFFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF | 0x00FFFFFF 00FFFFFF | 0x00FFFFFF 00FFFFFF
* | | 0xFFFFFFFF | 0xFFFFFFFF | 0xFFFFFFFF | 0x00FFFFFF
* ------------------------------------------------------------------------------------------------------
* | | 0xFFFFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF
* | 64bit | 0xFFFFFFFF FFFFFFFF | 0xFFFFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF
* | | 0xFFFFFFFF FFFFFFFF | 0xFFFFFFFF FFFFFFFF | 0xFFFFFFFF FFFFFFFF | 0x00FFFFFF FFFFFFFF
*/
低位在前
扇区头(32粒度) 36字节
字节序号 | 名称 | 字节数 | ||||
0-11 | 扇区存储状态 | 12 | 未使用 | 空 (置第0字节为0) | 使用 (置第0字节和第5字节为0) | 满 置第0字节、第5字节、第9字节 |
12(0C)-23 | 扇区脏状态 | 12 | 未使用 | 不脏 置第0字节为0 | 脏 置第0字节、第5字节、第9字节 | GC 置第0字节、第5字节、第9字节 |
24(18)-27 | magic | 4 | 0x30424446(FDB0) | |||
27-31 | combined | 4 | 0xFFFFFFFF | 合并后的下一扇区号 | ||
32-35(0x23) | reserved | 4 | 0xFFFFFFFF |
读出扇区信息时,比较magic和combined的值,如果对不上,返回初始化失败错误。
接着写入默认KV
static uint32_t boot_count = 0;
static time_t boot_time[10] = {0, 1, 2, 3};
/* default KV nodes */
static struct fdb_default_kv_node default_kv_table[] = {
{"username", "armink", 0}, /* string KV */
{"password", "123456", 0}, /* string KV */
{"boot_count", &boot_count, sizeof(boot_count)}, /* int type KV */
{"boot_time", &boot_time, sizeof(boot_time)}, /* int array type KV */
};
KV头,长度0x24(40字节)
字节序号 | 名称 | 字节数 | 内容 | |||||
0-19 | KV状态 | 20 | 未使用 | 预备写 | 写完成 | 预备删 | 删完成 | 错误头 |
20-23 | magic | 4 | 0x3030564B(KV00) | |||||
24-27 | KV总长度 | 4 | 0x38(56字节) 实际长度54,因为4字节对齐,所以56字节 | |||||
28-31 | Key CRC32 | 4 | C04EA3C4 | |||||
32-35 | Key name长度 | 4 | 8 | "username"长度(uint8_t类型,所以另3字节是0xFF) | ||||
36-39 | Val值长度 | 4 | 6 | "armink" | ||||
40-47 | Key | 8 | "username" | |||||
48-53 | val | 6 | "armink" |
当错误头时,只返回了“FDB_READ_ERR”状态,程序没有做处理。
此时数据如下:
扇区尾部保留空间。
参考:fdb_kvdb.c第894行,static bool alloc_kv_cb(kv_sec_info_t sector, void *arg1, void *arg2)。
#define FDB_KV_NAME_MAX 64
#define FDB_SEC_REMAIN_THRESHOLD (KV_HDR_DATA_SIZE + FDB_KV_NAME_MAX)
即40+64=104字节
sector->remain > arg->kv_size + FDB_SEC_REMAIN_THRESHOLD
即,最少保留104字节,最多保留104+KV-1字节。