文章目录
- nvs_flash(非易失性存储库)
- 简介
- 数据类型:
- 常用函数
- 应用实例
- 参考文档
nvs_flash(非易失性存储库)
简介
非易失性存储 (NVS) 库主要用于在 flash 中存储键值对格式
的数据。NVS 库通过调用esp_partition
API使用主 flash 的部分空间。nvs_flash库的封装,使用户操作更加便捷。
数据类型:
- 整数型:
uint8_t
、int8_t
、uint16_t
、int16_t
、uint32_t
、int32_t
、uint64_t
和int64_t
; - 以 0 结尾的字符串;
- 可变长度的二进制数据 (BLOB)
注:
- NVS 最适合存储一些较小的数据,而非字符串或二进制大对象 (BLOB) 等较大的数据。如需存储较大的 BLOB 或者字符串,请考虑使用基于磨损均衡库的 FAT 文件系统。
- 如果 NVS 分区被截断(例如,更改分区表布局时),则应擦除分区内容。可以使用 ESP-IDF 构建系统中的
idf.py erase-flash
命令擦除 flash 上的所有内容。 - 键必须唯一。为现有的键写入新值时,会将旧的值及数据类型更新为写入操作指定的值和数据类型。读取值时会执行数据类型检查。如果读取操作预期的数据类型与对应键的数据类型不匹配,则返回错误。
- 命名空间最多可占 15 个字符。单个 NVS 分区最多只能容纳 254 个不同的命名空间。不同命名空间可以有相同的键值。不同分区中也可以有相同的命名空间。一个句柄关联一个命名空间。
常用函数
/**
简介:初始化默认 NVS 分区。此 API 初始化默认 NVS 分区。默认的 NVS 分区是在分区表中标 记为“nvs”的分区。
返回值: ESP_OK存储是否已成功初始化。
ESP_ERR_NVS_NO_FREE_PAGES 如果 NVS 存储不包含空页(如果 NVS 分区被截断,则可能会发生这种情况)
ESP_ERR_NOT_FOUND如果在分区表中找不到带有标签“nvs”的分区
ESP_ERR_NO_MEM,以防无法为内部结构分配内存
**/
esp_err_t nvs_flash_init(void);
/**
简介:初始化指定分区的NVS闪存。
参数:const char *partition_label:初始化分区的名字.nvs_flash_init()函数的名字默 认为 "nvs"
返回值:上同
**/
esp_err_t nvs_flash_init_partition(const char *partition_label);
/**
简介:擦除默认的 NVS 分区。
**/
esp_err_t nvs_flash_erase(void);
esp_err_t nvs_flash_erase_partition(const char *part_name);
/**
简介:从默认 NVS 分区使用给定命名空间打开非易失性存储。
参数:namespace_name: 命名空间名称。最大长度为 (NVS_KEY_NAME_MAX_SIZE- 1)(15)个字符。不应为空。
open_mode:NVS_READWRITE 或 NVS_READONLY。如果NVS_READONLY,将打 开一个仅供读取的句柄。此句柄的所有写入请求都将被拒绝。
out_handle: 如果成功(返回代码为零),则在此参数中将返回句柄。
返回值: ESP_OK存储句柄是否已成功打开
ESP_FAIL是否存在内部错误;最有可能是由于 NVS 分区损坏(仅当禁用 NVS 断言检查时)
ESP_ERR_NVS_NOT_INITIALIZED如果存储驱动程序未初始化
如果找不到带有标签“nvs”的分区,则ESP_ERR_NVS_PART_NOT_FOUND
ESP_ERR_NVS_NOT_FOUND id 命名空间尚不存在,并且模式已NVS_READONLY
如果命名空间名称不满足约束,则ESP_ERR_NVS_INVALID_NAME
ESP_ERR_NO_MEM,以防无法为内部结构分配内存
ESP_ERR_NVS_NOT_ENOUGH_SPACE 如果没有新条目的空间或有太多不同的命名空间(允许的最大不同命名空间:254)
如果 NVS 分区是只读的,并且模式是NVS_READWRITE,则ESP_ERR_NOT_ALLOWED
ESP_ERR_INVALID_ARG 如果 out_handle 等于 NULL
**/
esp_err_t nvs_open(const char *namespace_name, nvs_open_mode_t open_mode, nvs_handle_t *out_handle);
/**
简介:为给定键设置int16_t值
参数:nvs_handle_t handle:nvs_open()赋值的句柄,应先调用nvs_open()。
const char *key:键值 最大长度为 (NVS_KEY_NAME_MAX_SIZE-1) 个字符。不应为空。
int16_t value:要设置的值
返回值:ESP_OK值是否设置成功
ESP_FAIL是否存在内部错误;最有可能是由于 NVS 分区损坏(仅当禁用 NVS 断言检查时)
ESP_ERR_NVS_INVALID_HANDLE句柄是否已关闭或为 NULL
ESP_ERR_NVS_READ_ONLY存储句柄是否以只读方式打开
ESP_ERR_NVS_INVALID_NAME键名称不满足约束
如果底层存储中没有足够的空间来保存值,则ESP_ERR_NVS_NOT_ENOUGH_SPACE
ESP_ERR_NVS_REMOVE_FAILED如果由于闪存写入操作失败而未更新该值。但是,该值已写 入,并且更新将在重新初始化 nvs 后完成,前提是闪存操作不会再次失败。
**/
esp_err_t nvs_set_i16(nvs_handle_t handle, const char *key, int16_t value);
/**
简介:给指定键设置字符串值。
参数:上同
返回值:上同
**/
esp_err_t nvs_set_str(nvs_handle_t handle, const char *key, const char *value);
/**
简介:给指定键设置二进制值。
参数: 上同
size_t length:要设置的二进制值的长度(单位:字节)
返回值:上同
**/
esp_err_t nvs_set_blob(nvs_handle_t handle, const char *key, const void *value, size_t length);
/**
简介:将任何挂起的更改写入非易失性存储。
参数:nvs_handle_t handle:句柄
返回值:ESP_OK更改是否已成功写入
ESP_ERR_NVS_INVALID_HANDLE句柄是否已关闭或为 NULL
**/
esp_err_t nvs_commit(nvs_handle_t handle);
/**
简介:获取给定键的int16_t值
参数:nvs_handle_t handle:句柄
const char *key:键值
int16_t *out_value: 指向输出值的指针
返回值:ESP_OK是否成功检索了该值
ESP_FAIL是否存在内部错误;最有可能是由于 NVS 分区损坏(仅当禁用 NVS 断言检查时)
ESP_ERR_NVS_NOT_FOUND请求的密钥是否不存在
ESP_ERR_NVS_INVALID_HANDLE句柄是否已关闭或为 NULL
ESP_ERR_NVS_INVALID_NAME键名称不满足约束
如果长度不足以存储数据,则ESP_ERR_NVS_INVALID_LENGTH
**/
esp_err_t nvs_get_i16(nvs_handle_t handle, const char *key, int16_t *out_value);
/**
简介:获取给定键的字符串值
参数:上同
char *out_value:指向输出值的指针
size_t *length:指向长度为 out_value 的变量的非零指针。如果out_value零,则将设置为保存值所需的长度。如果 out_value 不为零,则设置为写入值的实际长度。对于nvs_get_str这包括零终结符。
返回值:上同
**/
esp_err_t nvs_get_str(nvs_handle_t handle, const char *key, char *out_value, size_t *length);
/**
简介:初始化指定分区的NVS闪存。
参数:上同
返回值:上同
**/
esp_err_t nvs_set_blob(nvs_handle_t handle, const char *key, const void *value, size_t length);
/**
简介:关闭存储句柄并释放所有已分配的资源。
**/
void nvs_close(nvs_handle_t handle);
应用实例
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "nvs_flash.h"
#include "esp_log.h"
const char* TAG="NVSFLASH";
const char* NAMESPACE="nvsflash";
void app_main(void)
{
esp_err_t err=ESP_OK;
err=nvs_flash_init();
if(err==ESP_ERR_NVS_NO_FREE_PAGES){
ESP_ERROR_CHECK(nvs_flash_erase());
err=nvs_flash_init();
if(err==ESP_ERR_NVS_NO_FREE_PAGES){
ESP_LOGE(TAG, "nvs_flash_init error: %d\n", err);
return;
}
}
printf("Opening Non-Volatile Storage (NVS) handle... ");
nvs_handle_t nvs_handle;
/*
最大长度为(NVS_KEY_NAME_MAX_SIZE-1)默认为15个 字符。
*/
err=nvs_open(NAMESPACE,NVS_READWRITE,&nvs_handle);
if(err!=ESP_OK){
ESP_LOGE(TAG, "nvs_open error: %d\n", err);
return;
}
int16_t i=0;
size_t len=15;
char str[15];
uint8_t binary[4]={0x01,0x02,0x03,0x04};
uint8_t get_binary[4];
size_t get_binary_len=4;
nvs_set_i16(nvs_handle,"demo1",12);
nvs_set_str(nvs_handle,"demo2","HelloWorld");
nvs_set_blob(nvs_handle,"demo3",binary,sizeof(binary)/sizeof(uint8_t));
nvs_commit(nvs_handle);
nvs_get_i16(nvs_handle,"demo1",&i);
//长度必须非零并且必须指向out_value 中可用的长度。len=sizeof(str)/sizeof(char); 包括零终止符
nvs_get_str(nvs_handle,"demo2",str,&len);
nvs_get_blob(nvs_handle,"demo3",get_binary,&get_binary_len);
printf("demo1: %d\n",i);
printf("demo2: %s\n",str);
printf("demo3: %x,%x,%x,%x\n",get_binary[0],get_binary[1],get_binary[2],get_binary[3]);
nvs_close(nvs_handle);
/**
输出结果:
demo1: 12
demo2: HelloWorld
demo3: 1,2,3,4
*/
参考文档