ESP32数据存储 nvs

本文介绍了ESP32中NVS(non-volatile storage)库的基本使用方法,包括NVS库函数接口的学习、不同数据类型的存储与读取。通过具体代码示例展示了如何初始化NVS、打开命名空间、读写数据及提交更改。

这个实验的功能是使用乐鑫提供的 nvs 库去对 spi flash 的读写。 这个实验的代码为工程“3_9_nvs”目录。

3.9.1. 实验内容

(1) 学习 NVS 库函数接口
(2) 学习 NVS 存储/读取多种类型数据

3.9.2. ESP32 NVS 功能介绍

NVS总的来说,就是非易失性存储,类似MCU EEPROM,但实际上调用ESP32这些函数,数据是存储在FLASH中的。它的管理方式类似数据库的表,在NVS里面可以存储很多个不同的表,每个表下面有不同的键值,每个键值可以存储8位,16位,32位等等不同的数据类型,但不能是浮点数。
NVS相关API使用方法如下:
(1)初始化
调用“nvs_flash_init();”,如果失败可调用“nvs_flash_erase()”擦除NVS,然后再次初始化。
(2)打开一个表
nvs_open(“List”, NVS_READWRITE, &my_handle);
这个API第一个形参为一个字符串,可称为表名。第二个是读写模式,可选读写或者只读,第三个是当前打开的表的句柄。如此声明:“nvs_handle my_handle; ”。后面对表里面的键值进行读写,都需要输入键值所在表的句柄。
(3)读写
读:vs_get_i8(my_handle, “nvs_i8”, &nvs_i8);
读写不同的数据类型需要调用不同的API,类似的API有:“nvs_get_i16”,“nvs_get_u32”等等
形参方面,第一个是表的句柄,第二个是键值,第三个则是对应的变量的指针,如“nvs_i8”是个“int8_t”类型的变量。

     写:nvs_set_i8(my_handle, "nvs_i8", nvs_i8);
     基本跟读差不多,注意的是第三个形参变成了对应的变量,而不是变量的指针。

(4)提交与关闭
提交:
    nvs_commit(my_handle);
关闭:
    nvs_close(my_handle);

### ESP32-S3 使用 Arduino NVS 存储数据教程 #### 初始化NVS存储模块 为了确保能够正常读取和写入非易失性存储器,在程序启动时需要初始化NVS。这一步骤对于任何希望利用NVS功能的应用都是必不可少的。 ```cpp #include <nvs.h> #include <nvs_flash.h> void setup() { Serial.begin(115200); // 初始化NVS闪存 esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { // 如果NVS分区尚未被擦除,则执行此操作后再尝试重新初始化 ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } ESP_ERROR_CHECK(err); // 继续其他设置... } ``` 上述代码展示了如何安全地处理可能遇到的不同错误情况,比如当NVS页面已满或是版本不匹配时采取适当措施[^4]。 #### 向NVS中保存字符串类型的键值对 下面的例子说明了怎样把一个简单的字符串保存到指定命名空间下的特定键名处: ```cpp void saveStringToNVS(const char* namespaceName, const char* key, const String& value){ nvs_handle myHandle; esp_err_t err; // 打开或创建一个新的/现有的名称空间用于读写访问权限 err = nvs_open(namespaceName, NVS_READWRITE, &myHandle); if (err != ESP_OK) { Serial.printf("Error (%u) opening NVS handle!\n", err); return; } // 将字符串写入给定的key位置 err = nvs_set_str(myHandle, key, value.c_str()); if (err != ESP_OK) { Serial.printf("Error (%u) writing string to NVS\n", err); } else { // 提交更改至持久化存储nvs_commit(myHandle); Serial.println("Data written successfully"); } // 关闭句柄以释放资源 nvs_close(myHandle); } ``` 这段代码实现了向NVS内设定具体名字空间里边的一个字符串型别的条目,并且确认这些改动已经被提交到了永久性的储存区域之中[^1]。 #### 从NVS读回之前存储的信息 这里提供了一个函数来检索先前已经存在於相同命名空间内的某个键所对应的值: ```cpp String readStringFromNVS(const char* namespaceName, const char* key){ nvs_handle myHandle; size_t required_size; char *value = NULL; String result; esp_err_t err = nvs_open(namespaceName, NVS_READONLY, &myHandle); if (err != ESP_OK) { Serial.printf("Error (%u) opening NVS handle.\n", err); return ""; } // 获取所需缓冲区大小 err = nvs_get_str(myHandle, key, NULL, &required_size); if (err == ESP_OK && required_size > 0) { value = new char[required_size]; // 实际获取字符串内容 err = nvs_get_str(myHandle, key, value, &required_size); if (err == ESP_OK) { result = String(value); } else { Serial.printf("Error reading from NVS! %d\n", err); } delete[] value; // 清理动态分配的空间 } else { Serial.printf("Failed to determine the length of stored data or no such entry exists."); } nvs_close(myHandle); return result; } ``` 该部分逻辑负责查询并返回由`namespaceName`定义的作用域以及关联着`key`标识符的具体文本串对象;如果找不到对应记录则会给出提示信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bytechip

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

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

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

打赏作者

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

抵扣说明:

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

余额充值