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,由两个镜像存储空间,镜像空间用来做双备份。

用法流程

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

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

KV_ERROR key_value_cache_unregister_write_callback(void)

Unregister key value cache write callback.

返回:

KV_ERROR KV_OK success