1.简介

有时我们需要保存一些信息,然后在下次启动时使用。
我们希望这些数据在掉电的时候不会丢失。esp8266没有自己的rom,所以我们需要保存在外部flash中。
官方已经为我们提供了很多api,我们可以直接使用SDK中的components。

SDK编译环境搭建:https://blog.csdn.net/valonshen/article/details/104124127
由于esp8266文档中没有相关说明,参考esp32:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/api-reference/storage/nvs_flash.html#

非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。NVS 最适合存储一些较小的数据,而非字符串或二进制大对象 (BLOB) 等较大的数据。如需存储较大的 BLOB 或者字符串,请考虑使用基于磨损均衡库的 FAT 文件系统。

NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最大键长为 15 个字符,值可以为以下几种类型:

  1. 整数型:uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、uint64_t 和 int64_t;
  2. 以 \0 结尾的字符串;
  3. 可变长度的二进制数据 (BLOB)

2. 部分API介绍

esp_err_t nvs_flash_init(void)

初始化默认NVS分区,需要在其他API调用之前调用。esp8266将flash分成几个分区,每个分区的地址偏移和大小都可以自行配置,我会在另一个文章在介绍。

返回值

  • ESP_OK if storage was successfully initialized.
  • ESP_ERR_NVS_NO_FREE_PAGES if the NVS storage contains no empty pages (which may happen if NVS partition was truncated)
  • ESP_ERR_NOT_FOUND if no partition with label “nvs” is found in the partition table one of the error codes from the underlying
    flash storage driver

esp_err_t nvs_flash_erase(void)

擦除默认NVS分区所有数据。若要继续使用,需调用nvs_flash_init初始化。

返回值:

  • ESP_OK on success
  • ESP_ERR_NOT_FOUND if there is no NVS partition labeled “nvs” in the partition table

esp_err_t nvs_open(const char *name, nvs_open_mode_t open_mode, nvs_handle_t * out_handle)
void nvs_close(nvs_handle_t handle)

用于打开和关闭 NVS分区。name为最多15字节的命名空间,用于防止键值对名称的冲突。在不同的命名空间中允许出现相同名称的键值对,但在同一个命名空间中键值对的名称是唯一的。handle用于后续读写键值对操作。
目前使用esp8266的SDK,nvs打开的句柄类型需改成 nvs_handle,而esp-ief是nvs_handle_t

返回值:

  • ESP_OK if storage handle was opened successfully
  • ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized
  • ESP_ERR_NVS_PART_NOT_FOUND if the partition with label “nvs” is not found
  • ESP_ERR_NVS_NOT_FOUND id namespace doesn’t exist yet and mode is NVS_READONLY
  • ESP_ERR_NVS_INVALID_NAME if namespace name doesn’t satisfy constraints
  • other error codes from the underlying storage driver

参数:

  • name: Namespace name. Maximal length is determined by the underlying implementation, but is guaranteed to be at least 15 characters. Shouldn’t be empty.
  • open_mode: NVS_READWRITE or NVS_READONLY. If NVS_READONLY, will open a handle for reading only. All write requests will be rejected for this handle.
  • out_handle: If successful (return code is zero), handle will be returned in this argument.

esp_err_t nvs_set_i8(nvs_handle_t handle, const char *key, int8_t value)
esp_err_t nvs_set_u8(nvs_handle_t handle, const char *key, uint8_t value)
esp_err_t nvs_set_i16(nvs_handle_t handle, const char *key, int16_t value)
esp_err_t nvs_set_u16(nvs_handle_t handle, const char *key, uint16_t value)
esp_err_t nvs_set_i32(nvs_handle_t handle, const char *key, int32_t value)
esp_err_t nvs_set_u32(nvs_handle_t handle, const char *key, uint32_t value)
esp_err_t nvs_set_i64(nvs_handle_t handle, const char *key, int64_t value)
esp_err_t nvs_set_u64(nvs_handle_t handle, const char *key, uint64_t value)
esp_err_t nvs_set_str(nvs_handle_t handle, const char *key, const char *value)
esp_err_t nvs_get_i8(nvs_handle_t handle, const char *key, int8_t *out_value)

保存数值键值对,键的名字在同一命名空间内必须保持唯一,支持最长15字节的ASCII字符串。实际的存储操作将在nvs_commit被调用时完成。

返回值:

  • ESP_OK if value was set successfully
  • ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
  • ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only
  • ESP_ERR_NVS_INVALID_NAME if key name doesn’t satisfy constraints
  • ESP_ERR_NVS_NOT_ENOUGH_SPACE if there is not enough space in the underlying storage to save the value
  • ESP_ERR_NVS_REMOVE_FAILED if the value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again.
  • ESP_ERR_NVS_VALUE_TOO_LONG if the string value is too long

参数:

  • handle: Handle obtained from nvs_open function. Handles that were opened read only cannot be used.
  • key: Key name. Maximal length is determined by the underlying implementation, but is guaranteed to be at least 15
  • characters. Shouldn’t be empty.
  • value: The value to set. For strings, the maximum length (including null character) is 4000 bytes.

esp_err_t nvs_get_u8(nvs_handle_t handle, const char *key, uint8_t *out_value)
esp_err_t nvs_get_i16(nvs_handle_t handle, const char *key, int16_t *out_value)
esp_err_t nvs_get_u16(nvs_handle_t handle, const char *key, uint16_t *out_value)
esp_err_t nvs_get_i32(nvs_handle_t handle, const char *key, int32_t *out_value)
esp_err_t nvs_get_u32(nvs_handle_t handle, const char *key, uint32_t *out_value)
esp_err_t nvs_get_i64(nvs_handle_t handle, const char *key, int64_t *out_value)
esp_err_t nvs_get_u64(nvs_handle_t handle, const char *key, uint64_t *out_value)
esp_err_t nvs_get_str(nvs_handle_t handle, const char *key, char *out_value, size_t *length)

读取相应键值对的数据。

返回值

  • ESP_OK if the value was retrieved successfully
  • ESP_ERR_NVS_NOT_FOUND if the requested key doesn’t exist
  • ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
  • ESP_ERR_NVS_INVALID_NAME if key name doesn’t satisfy constraints
  • ESP_ERR_NVS_INVALID_LENGTH if length is not sufficient to store data

参数:

  • handle: Handle obtained from nvs_open function.
  • key: Key name. Maximal length is determined by the underlying implementation, but is guaranteed to be at least 15
  • characters. Shouldn’t be empty.
  • out_value: Pointer to the output value. May be NULL for nvs_get_str and nvs_get_blob, in this case required length will be returned in length argument.
  • length: A non-zero pointer to the variable holding the length of out_value. In case out_value a zero, will be set to the length required to hold the value. In case out_value is not zero, will be set to the actual length of the value written. For nvs_get_str this includes zero terminator.

esp_err_t nvs_commit(nvs_handle_t handle)

将修改的键值对写入flash。所以操作过键值对后,执行此命令。

返回值:

  • ESP_OK if the changes have been written successfully
  • ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
  • other error codes from the underlying storage driver

参数:

  • handle: Storage handle obtained with nvs_open. Handles that were opened read only cannot be used.

esp_err_t nvs_erase_key(nvs_handle_t handle, const char *key)

擦除某一命名空间的键值对。

3. 代码示例

#include <string.h>
#include <stdlib.h>
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "nvs.h"static const char* TAG = "main";void app_main(void)
{size_t length;char* buf ;// Initialize NVSesp_err_t err = nvs_flash_init();if (err == ESP_ERR_NVS_NO_FREE_PAGES) {// NVS partition was truncated and needs to be erased// Retry nvs_flash_initESP_ERROR_CHECK(nvs_flash_erase());err = nvs_flash_init();}ESP_ERROR_CHECK( err );// Openprintf("\n");printf("Opening Non-Volatile Storage (NVS) handle... ");nvs_handle my_handle;err = nvs_open("storage", NVS_READWRITE, &my_handle);if (err != ESP_OK) {printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));} else {printf("Done\n");}// Readprintf("Reading string from NVS ... \r\n");//若传入的buffer为null,数据长度将保存在length中err = nvs_get_str(my_handle, "string", NULL,&length);switch (err) {case ESP_OK:buf = (char*)malloc(length);if(nvs_get_str(my_handle,"string",buf,&length) == ESP_OK){ESP_LOGI(TAG,"get NVS data key: string, value: %s",buf);}else{ESP_LOGE(TAG,"get NVS data fault");}free(buf);nvs_erase_key(my_handle,"string");ESP_LOGI(TAG,"erase key");break;case ESP_ERR_NVS_NOT_FOUND:ESP_LOGI(TAG,"no found NVS Key");if( nvs_set_str(my_handle,"string","exampleString") == ESP_OK ){ESP_LOGI(TAG,"write key");}else{ESP_LOGE(TAG,"nvs key write fault");}break;default :printf("Error (%s) reading!\n", esp_err_to_name(err));}//需要commit才能生效修改nvs_commit(my_handle);nvs_close(my_handle);vTaskDelay(800);esp_restart();
}

执行

idf.py flash monitor

将打印如下信息:
第一次打印

Opening Non-Volatile Storage (NVS) handle… Done
Reading string from NVS …
I (305) main: no found NVS Key
I (312) main: write key
Done

等待8s重启,第二次打印

Opening Non-Volatile Storage (NVS) handle… Done
Reading string from NVS …
I (306) main: get NVS data key: string, value: exampleString
I (317) main: erase key

[ESP8266学习笔记]components_nvs 非易失性存储 Non-Volatile Storage(NVS),保存数据到flash相关推荐

  1. ESP8266学习笔记:实现ESP8266的局域网内通信

    ESP8266学习笔记:实现ESP8266的局域网内通信 现在就以实例入手.工程使用的是IOT_DEMO,据DEMO文档可以知道ESP8266初始工作模式为softAP+station共存的模式.于是 ...

  2. esp8266舵机驱动_arduino开发ESP8266学习笔记四—–舵机

    arduino开发ESP8266学习笔记四-–舵机 使用时发现会有ESP8266掉电的情况,应该是板上的稳压芯片的限流导致的,观测波形,发现当舵机运转时,电源线3.3V不再是稳定的3.3V,大概是在3 ...

  3. ESP8266学习笔记(1)——搭建环境、编译烧写(NONOS SDK)

    RTOS SDK环境搭建参看 ESP8266学习笔记(17)--搭建环境.编译烧写(RTOS SDK) 一.搭建环境 1.1 ESP8266 SDK 入门指南 官网下载:https://www.esp ...

  4. esp8266 蓝牙耳机_走进物联网智能家居-手把手带你制作wifi智能开关-ESP8266学习笔记(二)...

    走进物联网智能家居-手把手带你制作wifi智能开关-ESP8266学习笔记(二) 2020-05-09 13:44:11 9点赞 72收藏 6评论 小编注:此篇文章来自即可瓜分10万金币,周边好礼达标 ...

  5. python数据挖掘学习笔记】十六.逻辑回归LogisticRegression分析鸢尾花数据

    但是很多时候数据是非线性的,所以这篇文章主要讲述逻辑回归及Sklearn机器学习包中的LogisticRegression算法 #2018-03-28 16:57:56 March Wednesday ...

  6. Python数据挖掘学习笔记】九.回归模型LinearRegression简单分析氧化物数据

    #2018-03-23 16:26:20 March Friday the 12 week, the 082 day SZ SSMR [Python数据挖掘学习笔记]九.回归模型LinearRegre ...

  7. oracle查看表空间的内容,学习笔记:Oracle查看object对象 表空间 表 索引 数据文件的使用空间...

    天萃荷净 运维DBA咨询想要查看Oracle的object对象的使用空间大小,包括表空间 表 索引 数据文件的使用空间 1.查看Oracle表空间大小 Select Tablespace_Name,S ...

  8. python分析鸢尾花数据_python数据挖掘学习笔记】十六.逻辑回归LogisticRegression分析鸢尾花数据...

    但是很多时候数据是非线性的,所以这篇文章主要讲述逻辑回归及Sklearn机器学习包中的LogisticRegression算法 #2018-03-28 16:57:56 March Wednesday ...

  9. python爬取基金历史净值_Python学习笔记之抓取某只基金历史净值数据实战案例

    摘要:这篇Python开发技术栏目下的"Python学习笔记之抓取某只基金历史净值数据实战案例",介绍的技术点是"Python学习笔记.Python.历史净值数据.学习笔 ...

最新文章

  1. 电气论文:梯级水电站调度优化建模(文末有程序下载链接)
  2. 学会这21条,你离 Vim 大神就不远了!
  3. 这些新技术你们都知道吗?成功收获美团,小米安卓offer
  4. 湘潭大学 计算机学院程诗婕,云南大学学生获得2019CCF大学生计算机系统与程序设计竞赛西...
  5. 【博客话题】技术之路上的人和事
  6. [ocUI日记]UIwindow和UIview
  7. Java编程:马踏棋盘算法(骑士周游问题)
  8. 黑马程序员 oc中的类与对象
  9. CVPR2019| CVPR论文
  10. ios微信支付失败 php,iOS微信支付的那些坑
  11. 在菲律宾人民币换php怎么换,菲律宾汇率换算人民币(人民币兑换比索计算器)
  12. 计算机制图作品答辩,教师资格证考试小学信息技术《认识画图》答辩
  13. Matlab报错错误使用symengine
  14. Simulink电力电子仿真——(一)概述1
  15. 阿里巴巴回购雅虎股权 雅虎收购变成三巨头博弈
  16. Spring的依赖注入方法
  17. RK3568平台开发系列讲解(安卓篇)理解Android系统的编译
  18. MinGW下载和安装
  19. Leetcode动态规划专题(共38道)
  20. 《深度学习》(美)Ian Goodfellow 花书简要笔记(第一部分:应用数学与机器学习基础)

热门文章

  1. 西电捷通TISec解决方案保障配电网通信安全
  2. 小米手机安装Google框架
  3. Eclipse设置UTF-8编码格式
  4. Calendar类获取当前时间上一个月,下一个月,当月的最后一天等的处理方法
  5. react native 渐变 BVLinearGradient报错不存在
  6. flink学习思维导图
  7. 名帖109 鲜于枢 小楷《老子道德经卷》
  8. 90个外国英文网站强力推荐!!!
  9. LiveGBS国标GB/T28181如何配置按需云端录像(播放时候录像)和一直录像
  10. 高一数学试题-2022年秋期末试卷