ESP-IDF NVS
ESP-IDF NVS
目录
1. 什么是NVS?
非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。
2. NVS中的概念
2.1. partition 分区
这里的Flash分区与分区表中所提到的Flash分区是相同的概念。
所以在希望调用nvs_open_from_partition()
进行初始化时,需要先在分区表中设置对应名称的Flash分区。
在使用默认分区的情况下,可以直接使用nvs_open()
进行初始化。
2.2. namespace 命名空间
为了减少不同组件之间键名的潜在冲突,NVS将每个键值对分配给一个命名空间。
- 命名空间的命名规则遵循键名的命名规则,例如,最多可占15个字符。
- 单个NVS分区最多只能容纳254个不同的命名空间。
- 不同NVS分区中具有相同名称的命名空间将被视为不同的命名空间。
2.3. key-value 键值对
- 支持的最大键长为15个字符。
- 值可以分为以下几种类型:整数型;以0结尾的字符串;可变长度的二进制数据(BLOB)。
- 读取值时会执行数据类型检查。如果读取操作预期的数据类型与对应键的数据类型不匹配,则返回错误。
3. ESP-IDF中NVS的代码实现
基于nvs_flash_init()
和nvs_open(space_name, NVS_READWRITE, &my_handle)
实现的NVS
#include <stdio.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void app_main(void)
{
// 初始化NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
nvs_handle_t my_handle;
char* space_name = "storage";
err = nvs_open(space_name, NVS_READWRITE, &my_handle);
if (err != ESP_OK) {
printf("打开命名空间失败,具体错误 (%s) \n", esp_err_to_name(err));
} else {
printf("打开命名空间成功 \n");
// printf("Reading restart counter from NVS ... ");
int32_t restart_counter = 0;
char* key_name = "restart_counter";
err = nvs_get_i32(my_handle, key_name, &restart_counter); // 获取键值对restart_counter的值
switch (err) {
case ESP_OK:
printf("键值对restart_counter的值获取成功 \n");
printf("Restart counter的值为%ld\n", restart_counter);
break;
case ESP_ERR_NVS_NOT_FOUND:
printf("键值对restart_counter的值未被设置 \n");
break;
default :
printf("键值对restart_counter的值读取错误,具体错误 (%s) \n", esp_err_to_name(err));
}
// 更新restart_counter的值
restart_counter++;
err = nvs_set_i32(my_handle, key_name, restart_counter);
printf((err != ESP_OK) ? "设置键值对失败!\n" : "设置键值对成功\n");
// 提交写入值
err = nvs_commit(my_handle);
printf((err != ESP_OK) ? "提交写入值失败!\n" : "提交写入值成功\n");
nvs_close(my_handle);
}
printf("\n");
// 重启倒计时
for (int i = 10; i >= 0; i--) {
printf("%ds后重启设备...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("现在重启!\n");
esp_restart();
}