KEY value ========== 概述 ------ KEY value 模块提供参数掉电保存功能。 功能特性 ------------------- - 支持参数掉电保存。 - 支持碎片整理。 - 支持负载均衡。 - 支持 dump key 功能。 - 支持 kv cache 功能。 资源依赖 -------- - 宏开关 CONFIG_USE_COMP_KV - share_task(KV CACHE 使能) 键值对 -------- KV 的操作对象为键值对,其中键是 uint16_t 类型 id, 值为可变长的二进制数据 .. note:: 值当前上限为 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,由两个镜像存储空间,镜像空间用来做双备份。 用法流程 ---------- - 初始化 :cpp:func:`key_value_init` - 读操作 :cpp:func:`key_value_read_key` - 写操作 :cpp:func:`key_value_write_key` - 删除操作 :cpp:func:`key_value_del_key` API 介绍 ------------ .. doxygenfile:: key_value.h .. doxygenfile:: key_value_cache.h