《ESP-IDF入门指南》----->nvs_flash(非易失性存储库)

nvs_flash(非易失性存储库)


简介

非易失性存储 (NVS) 库主要用于在 flash 中存储键值对格式的数据。NVS 库通过调用esp_partitionAPI使用主 flash 的部分空间。nvs_flash库的封装,使用户操作更加便捷。

数据类型:
  1. 整数型:uint8_tint8_tuint16_tint16_tuint32_tint32_tuint64_tint64_t
  2. 以 0 结尾的字符串;
  3. 可变长度的二进制数据 (BLOB)

注:

  1. NVS 最适合存储一些较小的数据,而非字符串或二进制大对象 (BLOB) 等较大的数据。如需存储较大的 BLOB 或者字符串,请考虑使用基于磨损均衡库的 FAT 文件系统。
  2. 如果 NVS 分区被截断(例如,更改分区表布局时),则应擦除分区内容。可以使用 ESP-IDF 构建系统中的 idf.py erase-flash 命令擦除 flash 上的所有内容。
  3. 键必须唯一。为现有的键写入新值时,会将旧的值及数据类型更新为写入操作指定的值和数据类型。读取值时会执行数据类型检查。如果读取操作预期的数据类型与对应键的数据类型不匹配,则返回错误。
  4. 命名空间最多可占 15 个字符。单个 NVS 分区最多只能容纳 254 个不同的命名空间。不同命名空间可以有相同的键值。不同分区中也可以有相同的命名空间。一个句柄关联一个命名空间。

常用函数

  1. /**
    简介:初始化默认 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);
    
  2. /**
    简介:从默认 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);
    
  3. /**
    简介:为给定键设置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);
    
    
  4. /**
    简介:将任何挂起的更改写入非易失性存储。
    参数:nvs_handle_t handle:句柄
    返回值:ESP_OK更改是否已成功写入
          ESP_ERR_NVS_INVALID_HANDLE句柄是否已关闭或为 NULL
    **/
    esp_err_t nvs_commit(nvs_handle_t handle);
    
  5. /**
    简介:获取给定键的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);
    
  6. /**
    简介:关闭存储句柄并释放所有已分配的资源。
    
    **/
    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
    */

参考文档

  1. https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/storage/nvs_flash.html
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
nvs_flash_init函数是ESP-IDFESP32 IoT Development Framework)的一个重要函数,用于初始化Flash驱动器的非易失性存储(NVS)分区。NVS分区是ESP32用于存储应用程序参数和配置的重要分区之一。该函数的目的是在ESP32启动时初始化NVS分区,以便应用程序可以访问和写入NVS存储器。以下是nvs_flash_init()函数的详细讲解: 函数原型:esp_err_t nvs_flash_init(void) 函数返回值:esp_err_t类型,如果函数执行成功,则返回ESP_OK,否则返回错误代码 函数功能:该函数用于初始化Flash驱动器的NVS分区。在ESP32启动时,该函数应该被调用一次,以便应用程序可以访问和写入NVS存储器。 函数说明:该函数是ESP-IDF的一个重要函数,需要在应用程序主函数之前调用。如果未初始化NVS分区,则应用程序将无法访问和写入NVS存储器。在调用该函数之前,需要确保已经初始化了ESP32的Flash驱动器。 函数示例: ``` #include <nvs_flash.h> void app_main(void) { // 初始化Flash驱动器的NVS分区 esp_err_t ret = nvs_flash_init(); if (ret == ESP_OK) { printf("NVS分区初始化成功"); } else { printf("NVS分区初始化失败"); } } ``` 需要注意的是,nvs_flash_init()函数仅需要在ESP32首次启动时调用一次,并且不应该在应用程序的主循环重复调用该函数。如果应用程序需要重新初始化NVS分区,则可以使用nvs_flash_erase()函数清除NVS分区的数据,并再次调用nvs_flash_init()函数以重新初始化NVS分区。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知名小白11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值