更新时间:2023-12-19 08:36:58下载pdf
键值存储(KV DB)是一个小型键值(key-value,KV)存储数据库模块,提供小型数据的存储、检索等功能。
存储器划分出一块连续的存储空间(32KB 或者 64KB),并在该空间按照 4KB 划分出 block,最后在每个 block 中按照 128B 划分出一个一个 page。
page 按照用途可以分为:
管理页:每个 block 的第一个 page 是作为管理页,您维护该 block 中每个 page 的使用情况。
索引页:用于包括 key 以及 key 对应的 value 的开始、结束 page 地址,每一个 key 独占一个 page。
数据页:用于存储 value,可以跨多个 page 存储。
适用于按照 key-value 的形式,将数据存储新到 KV DB 中,并支持读取、删除和编辑等操作。
KV DB 初始化是在设备产测的时候完成的,一般不需要您关注。如果您不使用涂鸦的产测工具,您需要对 KV DB 进行初始化/格式化。
/**
* @brief tuya key-value database initialization in mf
*
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note user don't need to care about this function, it will be called during tuya IoTOS initialization.
*
*/
OPERATE_RET ws_db_init_mf(VOID);
向 KV DB 写入一组 key-value 数据,需要提供 key、value 以及 value 的长度。
/**
* @brief tuya key-value database write entry
*
* @param[in] key key of the entry you want to write
* @param[in] value value buffer you want to write
* @param[in] len the numbers of byte you want to write
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*/
OPERATE_RET wd_common_write(IN CONST CHAR_T *key, IN CONST BYTE_T *value, IN CONST UINT_T len);
从 KV DB 中读取一组 key-value 数据,需要提供 key,并提供一个用于存储 value 的缓冲区和缓冲区的长度。读取成功之后,获得 value 以及 value 的长度。
/**
* @brief tuya key-value database read entry
*
* @param[in] key key of the entry you want to read
* @param[out] value buffer of the value
* @param[out] p_len length of the buffer
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note must free the value buffer with wd_common_free_data when you no longer need the buffer
*/
OPERATE_RET wd_common_read(IN CONST CHAR_T *key, OUT BYTE_T **value, OUT UINT_T *p_len);
从 KV DB 中删除一组 key-value 数据,需要提供 key。
/**
* @brief delete the entry from key-value database
*
* @param[in] key key of the entry you want to delete
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*/
OPERATE_RET wd_common_delete(IN CONST CHAR_T *key);
使用模糊匹配的方式,从 KV DB 中读取一组符合包含 key 的 key-value 数据,需要提供 fuzzy key(key 的子段),并提供一个用于存储 value 的缓冲区和缓冲区的长度。读取成功之后,获得 value 以及 value 的长度,wd_common_fuzzy_read
会按照查找的 index 逐个返回查找命中的 key-value 数据。
/**
* @brief tuya key-value database fuzzy read entry
*
* @param[in] fuzzy_name key of the entry you want to read
* @param[in] index index of the value sequnence
* @param[out] data buffer of the value
* @param[out] p_len length of the buffer
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note if we have three entries "x1","x2","x3" in database, and read use "x" as the key will got all these 3 entries
* and will choose the return entry by index
*
* @note must free the value buffer with wd_common_free_data when you no longer need the buffer
*/
OPERATE_RET wd_common_fuzzy_read(IN CONST CHAR_T *fuzzy_name, INOUT UINT_T *index, OUT BYTE_T **data, OUT UINT_T *len);
使用模糊匹配的方式,从 KV DB 中删除一组符合包含 key 的 key-value 数据,需要提供 fuzzy key(key 的子段)。
/**
* @brief fuzzy delete the entry from key-value database
*
* @param[in] key key of the entry you want to delete
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note delete all entries if the key matches the prefix of entry key
*/
OPERATE_RET wd_common_fuzzy_delete(IN CONST CHAR_T *key);
专门用于 key user_param_key
写入的接口,user_param_key
是一个专用于您自定义数据存储的 key。因此,不需要输入 key。
/**
* @brief write the user parameter to the Tuya key-value database
*
* @param[in] data buffer of the data
* @param[in] len length of the data
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note the key of user parameter entry is "user_param_key"
*/
OPERATE_RET wd_user_param_write(IN CONST BYTE_T *data, IN CONST UINT_T len);
专门用于 key user_param_key
读取的接口,user_param_key
是一个专用于您自定义数据存储的 key。因此,不需要输入 key。
/**
* @brief read the user parameter from tuya key-value database
*
* @param[out] buf buffer of the data
* @param[out] len length of the data
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*
* @note the key of user parameter entry is "user_param_key",must free the value buffer with
* wd_common_free_data when you nolonger need the buffer
*/
OPERATE_RET wd_user_param_read(OUT BYTE_T **buf, OUT UINT_T *len);
释放 wd_common_read
、wd_common_fuzzy_read
、wd_user_param_read
时申请的资源。注意,在使用 wd_common_read
和 wd_common_fuzzy_read
成功之后,必须调用 wd_common_free_data
接口,否则会造成内存泄露。
/**
* @brief free the buffer which is allocated by wd_common_read or wd_common_fuzzy_read
*
* @param[in] data the buffer got from wd_common_read or wd_common_fuzzy_read
* @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
*/
OPERATE_RET wd_common_free_data(IN BYTE_T *data);
sample_kv_demo()
{
int rt = OPRT_OK;
// 写一个数据"ddi-xxx":"hello-world-x"
rt = wd_common_write("ddi-xxx", "hello-world-x", 13);
EXPECT_EQ(rt, OPRT_OK);
// 读取数据"ddi-xxx",需要 wd_common_free_data
BYTE_T *value = NULL;
UINT_T len = 0;
rt = wd_common_read("ddi-xxx", &value, &len);
EXPECT_EQ(rt, OPRT_OK);
EXPECT_EQ(memcmp(value, "hello-world-x", 13), 0);
wd_common_free_data(value);
value = NULL;
len = 0;
// 写一个数据"ddi-xxx":"hello-world-y"
rt = wd_common_write("ddi-yyy", "hello-world-y", 13);
EXPECT_EQ(rt, OPRT_OK);
// 修改数据"ddi-xxx":"hello-world-z"
rt = wd_common_write("ddi-xxx", "hello-world-z", 13);
EXPECT_EQ(rt, OPRT_OK);
// 读取所有包含"ddi-"的数据,会自动迭代读取全部数据
UINT index = 0;
while(rt == OPRT_OK) {
rt = wd_common_fuzzy_read("ddi-", &index, &value, &len);
if(value) {
wd_common_free_data(value);
value = NULL;
}
}
// 删除数据"ddi-xxx"
rt = wd_common_delete("ddi-xxx");
EXPECT_EQ(rt, OPRT_OK);
// 删除所有包含"ddi-"的数据
rt = wd_common_fuzzy_delete("ddi-");
EXPECT_EQ(rt, OPRT_OK);
return OPRT_OK;
}
可以的,但需要注意 KV DB 的存储空间是有限的,一般是 32KB。另外,读写 KV DB 不要过于频繁,特别是在设备启动过程中尽量避免读写 KV DB。一方面比较耗时,影响设备启动时间。另一方面,设备启动过程中电压不稳,容易造成 Flash 失效。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈