Keep data

NVS persistent keys

SSID, calibration and serial belong here, not in RAM.

Keep data Saved settings ESP32 family

Official path: examples/storage/nvs_rw_value

01 Overview

NVS (Non-Volatile Storage) is a lightweight key-value store provided by ESP-IDF, backed by a dedicated partition in the module's internal flash. It is designed for small data items such as configuration parameters, calibration data, counters, and device flags.

Unlike RAM, NVS retains data across power cycles, making it the default place to store Wi-Fi credentials, device serial numbers, user settings, and other critical information. Using NVS avoids re-configuring the device on every boot and preserves user data across OTA updates.

Typical use cases include saving provisioning results (e.g., SSID and password), storing sensor calibration offsets, recording device operation counts, and saving user interface preferences. It is not suitable for large files (firmware, logs, images) — use SPIFFS or SD card for those.

NVS supports multiple namespaces, each containing multiple key-value pairs. Key names are limited to 15 characters, and value types include integers, strings, and binary blobs.

NVS includes wear leveling and power-loss safety mechanisms, but frequent writes accelerate flash wear. Therefore, design write frequency carefully, e.g., cache counters or use wear-leveling algorithms.

In ESP-IDF, NVS is the underlying storage for many components (Wi-Fi, Bluetooth), so understanding it is essential for reliable firmware development.

02 Hardware

  • Storage medium: Uses the NVS partition in the module's internal flash; no extra chip required. The partition table is defined at compile time and includes an nvs partition by default.
  • Flash wear: NVS is flash-based, with limited write cycles (about 100k). Frequent writes (e.g., every second) will quickly exhaust the lifetime; implement software caching or reduce write frequency.
  • Power-loss protection: NVS writes have power-loss safety, but extreme cases (e.g., power cut mid-write) may corrupt data; consider backup or checksums for critical data.
  • Partition size: The NVS partition size is configured in the partition table, default 24KB. Adjust if more storage is needed, but be careful not to crowd out firmware space.
  • Encryption support: NVS supports flash encryption to protect sensitive data (e.g., Wi-Fi passwords). Enabling it requires key management.
  • No external connections: This example involves no external hardware; it relies solely on the module's flash.

03 Software flow

1. Call `nvs_flash_init()` to initialize the NVS library. If it returns an error (e.g., partition erased), erase and re-init with `nvs_flash_erase()`.

2. Open a namespace (e.g., "storage") using `nvs_open()` with read/write mode.

3. Use `nvs_get_*` or `nvs_set_*` functions to read/write keys. For example, read SSID or write calibration values.

4. After writing, you must call `nvs_commit()` to commit changes to flash; otherwise data is not actually saved.

5. Handle read failures: if a key does not exist, the function returns a specific error code; use default values or initialize then.

6. On firmware upgrades, if key structure changes, write migration logic: read old keys, convert to new format, delete old keys.

7. For Wi-Fi credentials, you can use `esp_wifi_set_storage(WIFI_STORAGE_FLASH)` to let the Wi-Fi driver manage NVS automatically, avoiding manual read/write.

8. Optionally enable NVS encryption using `nvs_flash_secure_init()` and configure a key partition.

04 Core points

  • No commit means no save: Forgetting to call `nvs_commit()` is a common mistake; data stays only in cache and is lost on power-off.
  • Frequent writes wear flash: For high-frequency updates like counters, accumulate in RAM and write to NVS periodically.
  • Key name length limit: Key names are limited to 15 characters; exceeding causes errors, so design accordingly.
  • Version migration: After firmware upgrades, key formats may change; check version at boot and migrate data.
  • Don't store large files: NVS is for small data; use SPIFFS or SD card for large files.
  • Customizable: Design a config model per product, use multiple namespaces, and enable encrypted NVS for sensitive data.

中文

掉电还在

NVS 掉电保存

SSID、标定值、序列号要放这里,不能只放 RAM。

掉电还在 保存配置 ESP32 family

官方路径: examples/storage/nvs_rw_value

01 项目概述

NVS(非易失性存储)是 ESP-IDF 提供的一个轻量级键值存储库,数据保存在模组内部 Flash 的专用分区中。它专为小数据量设计,适合保存配置参数、校准数据、运行计数器和设备标志位。

与 RAM 不同,NVS 中的数据在掉电后依然保留,因此它是存放 Wi-Fi 凭据、设备序列号、用户设置等关键信息的默认选择。使用 NVS 可以避免每次上电都重新配置设备,也方便 OTA 升级后保留用户数据。

NVS 的典型应用场景包括:保存配网结果(如 SSID 和密码)、存储传感器校准偏移量、记录设备运行次数、保存用户界面偏好等。它不适合存储大文件(如固件、日志、图片),这些应使用 SPIFFS 或 SD 卡。

NVS 支持多个命名空间(namespace),每个命名空间内可包含多个键值对。键名长度有限制(最长 15 字符),值类型支持整数、字符串、二进制块等。

NVS 还支持磨损均衡和掉电安全机制,但频繁写入会加速 Flash 磨损,因此需要合理设计写入频率,例如对计数器进行缓存或使用磨损均衡算法。

在 ESP-IDF 中,NVS 是许多组件(如 Wi-Fi、蓝牙)的底层存储,理解其用法是开发可靠固件的基础。

02 项目硬件描述

  • 存储介质: 使用模组内部 Flash 的 NVS 分区,无需额外芯片。分区表在编译时定义,默认包含 nvs 分区。
  • Flash 磨损: NVS 基于 Flash,写入次数有限(约 10 万次)。频繁写入(如每秒记录)会迅速耗尽寿命,需在软件层做缓存或降频。
  • 掉电保护: NVS 写入具有掉电安全机制,但极端情况下(如写入中途掉电)可能导致数据损坏,建议对关键数据使用备份或校验。
  • 分区大小: NVS 分区大小在分区表中配置,默认 24KB。若需存储更多数据,可调整分区表,但注意不要挤占固件空间。
  • 加密支持: NVS 支持 Flash 加密,可保护敏感数据(如 Wi-Fi 密码)。启用后需处理密钥管理。
  • 无外部连接: 本示例不涉及任何外部硬件,仅依赖模组自身 Flash。

03 项目软件流程描述

1. 调用 `nvs_flash_init()` 初始化 NVS 库。若返回错误(如分区被擦除),需先执行 `nvs_flash_erase()` 再重新初始化。

2. 使用 `nvs_open()` 打开一个命名空间(如 "storage"),指定读写模式。

3. 使用 `nvs_get_*` 或 `nvs_set_*` 函数读写键值。例如,读取 SSID 或写入校准值。

4. 写入后必须调用 `nvs_commit()` 将更改提交到 Flash,否则数据不会真正保存。

5. 处理读取失败的情况:若键不存在,返回特定错误码,此时应使用默认值或进行初始化。

6. 固件升级时,若键结构变化,需编写迁移逻辑:读取旧键,转换为新格式,删除旧键。

7. 对于 Wi-Fi 凭据,可直接使用 `esp_wifi_set_storage(WIFI_STORAGE_FLASH)` 让 Wi-Fi 驱动自动管理 NVS,无需手动读写。

8. 可选:启用 NVS 加密,使用 `nvs_flash_secure_init()` 并配置密钥分区。

04 项目核心点

  • 没 commit 等于没保存: 忘记调用 `nvs_commit()` 是常见错误,数据只留在缓存中,掉电即失。
  • 频繁写入会磨损 Flash: 计数器等高频更新数据应先在 RAM 中累加,定期写入 NVS。
  • 键名长度限制: 键名最长 15 字符,超长会报错,设计时需注意。
  • 版本迁移: 固件升级后,键的格式可能变化,需在启动时检查版本号并迁移数据。
  • 不要存大文件: NVS 适合小数据,大文件请用 SPIFFS 或 SD 卡。
  • 可定制: 根据产品需求设计配置模型、使用多个命名空间、启用加密 NVS 保护敏感数据。