KEY value
概述
KEY value 模块提供参数掉电保存功能。
功能特性
支持参数掉电保存。
支持碎片整理。
支持负载均衡。
支持 dump key 功能。
支持 kv cache 功能。
资源依赖
宏开关 CONFIG_USE_COMP_KV
share_task(KV CACHE 使能)
键值对
KV 的操作对象为键值对,其中键是 uint16_t 类型 id, 值为可变长的二进制数据
备注
值当前上限为 4096 - 16 - 12 KEY_VALUE_KEY_MAX_VALUE_LENGTH 字节, 实际存储到介质中会强制 aligne 成 4 字节对齐,方便 cache 寻址。
键必须唯一。为现有的键写入新值时,会将旧的值及数据类型更新为写入操作指定的值和数据类型。
页面结构
当前,我们假设 flash 扇区大小为 4096 字节。
页面由头部、条目状态位图和条目三部分组成。该条目仅保存一个键值对的部分内容(更多信息详见条目结构描述)。
页面结构如下图所示,括号内数字表示该部分的大小(以字节为单位)。
+------------+------------+------------+--------+--------------+---------+
| type (4) | state (4) | magic (4) | id(2) | version (1) | hec (1) | 页头部 (16)
+----------+-----------+---------+-----------+-------+-----------+-------+
| state(4) |length (2) | crc (1) | unused(1) | id(2) | w_able (1)| hec(1)| key 头部 (12)
+------------------------------------------------------------------------+
| Payload |
+------------------------------------------------------------------------+
| state(4) |length (2) | crc (1) | unused(1) | id(2) | w_able (1)| hec(1)| key 头部 (12)
+------------------------------------------------------------------------+
| Payload |
+------------------------------------------------------------------------+
| state(4) |length (2) | crc (1) | unused(1) | id(2) | w_able (1)| hec(1)| key 头部 (12)
+------------------------------------------------------------------------+
| Payload |
+------------------------------------------------------------------------+
/ ... /
/ ... /
+------------------------------------------------------------------------+
通过将 0 写入某些位可以定义页面状态值,表示状态改变。state 有以下几种情况: KV_PAGE_STATE_EMPTY 0xFFFFFFFF 表示初始化状态,未使用 KV_PAGE_STATE_USING 0xFFFFFF00 表示使用中 KV_PAGE_STATE_DEFRAGGING 0xFFFF0000 表示在回收中
页头部中的 version 字段反映了所用的 KV 格式版本,目前已经实现向后兼容,版本升级从 1 开始依次递增(例如,version-1 为 1,version-2 为 2,以此类推)。
页头部中 HEC 值是由 PAGE 头成员异或值得到。
条目结构和条目状态位图的详细信息见下文描述。
条目和条目状态位图
每个条目可处于以下三种状态之一,每个状态在条目状态位图中用四位表示。
- 空 (0xFFFFFFFF)
条目还未写入任何内容,处于未初始化状态(全部字节为
0xFFFFFFFF)。- 写入(0xFFFFFF00)
一个键值对正在写入条目中。
- 使用(0xFFFF0000)
一个键值对正在写入条目中完成,并当前有效。
- 删除(0xFF000000)
一个键值对正在删除中。
- 无效(0x00000000)
一个键值置为成无效,删除完成。
flash 扇区映射如下,KV 更新时会顺序写入键值对,并清除老的键值对状态信息,只到 page 为满会做回收,会始终存在一个 page 来做回收使用,如图,当 page3 满后会开始触发回收,将 page1,page2 中的 valid key move 到 empty page,然后move完成一个 page,将该 page 状态置为成 empty. 两个镜像分区动作一致
+-------------------------+
| Main Page |
+-------------------------+
+--------+ +--------+ +--------+ +--------+
| Page 1 | | Page 2 | | Page 3 | | Page 4 |
| Full +---> | Full +---> | Active | | Empty | <- 状态
| #11 | | #12 | | #14 | | | <- 序列号
+---+----+ +----+---+ +----+---+ +---+----+
| | | |
| | | |
| | | |
+---v------+ +-----v----+ +------v---+ +------v---+
| Sector 0 | | Sector 1 | | Sector 2 | | Sector 3 | <- 物理扇区
+----------+ +----------+ +----------+ +----------+
+-------------------------+
| Backup Page |
+-------------------------+
+--------+ +--------+ +--------+ +--------+
| Page 1 | | Page 2 | | Page 3 | | Page 4 |
| Full +---> | Full +---> | Active | | Empty | <- 状态
| #11 | | #12 | | #14 | | | <- 序列号
+---+----+ +----+---+ +----+---+ +---+----+
| | | |
| | | |
| | | |
+---v------+ +-----v----+ +------v---+ +------v---+
| Sector 4 | | Sector 5 | | Sector 6 | | Sector 7 | <- 物理扇区
+----------+ +----------+ +----------+ +----------+
KV 分区存储位置
根据 boomap 定义,KV 分区数据占用位置由 IMAGE_TYPE_KV 定义, 大小一般有 8 个 sector,由两个镜像存储空间,镜像空间用来做双备份。
用法流程
初始化
key_value_init()删除操作
key_value_del_key()
API 介绍
Defines
-
KV_VERSION_1_0
KEY-VALYE VERSION 1.0.
-
KV_VERSION_2_0
KEY-VALYE VERSION 2.0.
-
KV_VERSION_LATEST
LATEST KEY-VALYE VERSION 2.0.
Enums
-
enum KV_ERROR
Values:
-
enumerator KV_OK
OK, NO error
-
enumerator KV_UNKONWN_ERROR
UNKONW error
-
enumerator KV_NOT_INIT
kv not initial
-
enumerator KV_WRITE_ERROR
kv write error
-
enumerator KV_READ_ERROR
kv read error
-
enumerator KV_TOO_FEW_PAGES
kv page is not enough
-
enumerator KV_PAGE_NOT_FOUND
kv page is not found
-
enumerator KV_KEY_NOT_FOUND
kv key is not found
-
enumerator KV_FLASH_ERROR
kv flash operation error
-
enumerator KV_PAGE_STATE_ERROR
kv page state is error
-
enumerator KV_KEY_STATE_ERROR
kv key state is error
-
enumerator KV_PERMISSION_DENIED
modify a read only key
-
enumerator KV_NO_ENOUGH_SPACE
kv space is not enough
-
enumerator KV_LENGTH_ERROR
key length error
-
enumerator KV_NO_MEM
kv malloc error
-
enumerator KV_FAIL
kv operate fail
-
enumerator KV_OK
Functions
-
KV_ERROR key_value_defrag(void)
This function is used to defrag in key value.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_init(bool format)
This function is used to init in key value.
- 参数:
format -- Format the section if magic check fail.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_force_reset(void)
This function is used to force reset in key value.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_write_key(uint16_t id, const uint8_t *data, uint32_t length, bool writeable)
Write a key to flash.
备注
Thread unsafe
- 参数:
id -- is struct key info's id.
data -- is write data.
length -- is the length of write data.
writeable -- is write or not.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_read_key(uint16_t id, uint8_t **data, uint32_t *length)
Read a key to flash.
备注
Thread unsafe
- 参数:
id -- Struct key info's id.
data -- Pointer of data save pointer.
length -- Key data length.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_del_key(uint16_t id)
Remove a key.
- 参数:
id -- is struct key info's id.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_set_key(uint16_t id, const uint8_t *data, uint32_t length, bool writeable)
The main API for set a key.
- 参数:
id -- is struct key info's id.
data -- is write data.
length -- is the length of write data.
writeable -- is write or not.
- 返回:
KV_OK for success otherwise error code.
-
KV_ERROR key_value_get_key(uint16_t id, uint8_t **data, uint32_t *length)
This function is used to get key in key value.
- 参数:
id -- is struct key info's id.
data -- is get kv value's data.
length -- is the length of get kv header data.
- 返回:
KV_OK for success otherwise error code.
-
void key_value_dump_all_keys(void)
This function is used to dump all keys in key value.
-
uint8_t key_value_get_page_num(void)
This function is used to get kv page number, decided by kv version.
-
uint8_t key_value_get_version(void)
This function is used to get kv version.
Typedefs
-
typedef void (*key_value_cache_write_callback)(void)
Callback after key value cache is written.
Functions
-
KV_ERROR key_value_cache_invalid(void)
Invalid all key value at memory cache.
参见
KV_OK for success otherwise fail
备注
key will cached again at next read/write.
备注
write key at key value cache will lost
- 返回:
KV_ERROR
-
KV_ERROR key_value_cache_flush(void)
Write cached key to flash.
参见
KV_OK for success otherwise fail
- 返回:
KV_ERROR
-
KV_ERROR key_value_cache_register_write_callback(key_value_cache_write_callback cb)
Register key value cache write callback.
参见
key_value_cache_write_callback
- 参数:
cb -- [in]
- 返回:
KV_ERROR
KV_OK success
KV_FAIL A callback has been registered