General Steps
Note
This document is automatically translated using AI. Please excuse any detailed errors. The official English version is still in progress.
This document summarizes the general implementation process of Non-Volatile Storage (NVS) in ESP-IDF, covering its basic description, initialization steps, and related execution process.
By mastering the content of this document, developers can quickly understand the key logic related to NVS, providing a unified reference for subsequent example learning.
Non-Volatile Storage (NVS)
Overview
NVS (Non-Volatile Storage) is a non-volatile storage mechanism provided by ESP, the data saved in it will not be lost even if the device is powered off or restarted. It provides developers with a lightweight, reliable way to store device configurations, status information, or tag-like data. The design philosophy of NVS is simplicity, structure, and persistence, with the core feature being the storage of data in key-value pairs, and organization and isolation through namespaces, thus avoiding data conflicts between different modules. NVS ensures data safety through its internal page management mechanism and provides standard APIs for read, write, update, and delete operations.
Flash Storage Characteristics
The data of NVS is ultimately stored on the Flash of the ESP chip, so the characteristics of Flash directly affect the use of NVS:
Page Erase: Flash data operates in pages, each page is usually 4 KB or 16 KB, and the entire page must be erased before writing.
Limited Erase Life: Each storage unit has a limited number of erase times (for example, 100,000 times), and frequent erasing will accelerate Flash wear.
Page Management Mechanism: When NVS writes or updates data, if the page space is insufficient, it will trigger garbage collection, move valid data to a new page and erase the old page, to ensure data integrity.
Due to these characteristics, NVS is not suitable for storing large files or frequently updated data, such as audio files, log files, etc., otherwise, it may easily cause premature damage to Flash and performance degradation. NVS is more suitable for storing small amounts of simple structured data, such as:
Configuration Information: Wi-Fi SSID, password, Bluetooth pairing information, etc.
User Settings: Brightness, volume, language preference, etc.
Status Information: For example, the mode of the last run, counter values, etc.
Key-Value Pair
The core storage unit of NVS is the key-value pair, each piece of data is stored in the form of a key-value pair, thus achieving efficient and safe search, update, and delete operations. Each key-value pair consists of two parts:
Key: Similar to a label or name, it is a string type, used to uniquely identify a piece of data, with limited length (up to 15 characters).
Value: The actual data to be saved, can store various data types, including integers (int32_t, int64_t), strings, or binary data (blob).
When writing new data, NVS will find free page space to store the new value. When updating an existing key, the old value will be marked as invalid, and the new value will be written to the free position to ensure data safety. The concept of key-value pairs makes NVS flexible in managing different types of data, and data can be quickly accessed through the index of unique keys. For other explanations, please refer to Key-Value Pair.
Namespace
The namespace is a mechanism used by NVS to isolate data from different modules. Each namespace independently manages its own set of key-values to avoid conflicts caused by different modules using the same key name, while providing logical grouping for easy management and access.
Internally in Flash, NVS manages pages according to the namespace. When writing or updating data, it will locate the page where the corresponding namespace is located; if the page is full, it will trigger garbage collection, move valid data to a new page and erase the old page, thus ensuring data integrity and safety. For other explanations, please refer to Namespace.
NVS General Steps
NVS Initialization
Initialize Non-Volatile Storage:
Call
nvs_flash_init()
to initialize NVS, completing the preparation and mounting of the storage medium. For related parameter descriptions, please refer to Non-Volatile Storage Library API.
Check the Return Value:
Timely discover potential problems during the initialization process, such as NVS partition being full or version mismatch, to avoid errors when reading and writing data later, leading to functional abnormalities or even crashes.
If an exception is returned, call
nvs_flash_erase()
to erase the NVS partition. For related parameter descriptions, please refer to Non-Volatile Storage Library API.
ESP_ERR_NVS_NO_FREE_PAGES
: Indicates that the NVS partition is full, there are no available free pages, and new data cannot be written.
ESP_ERR_NVS_NEW_VERSION_FOUND
: Indicates that the data version of the current NVS partition does not match the version expected by the library, and it may be necessary to upgrade or format the partition.After erasing the partition, you need to call the initialization function again and check the return value again to ensure successful initialization.
Open NVS Handle
Create a
nvs_handle_t
type handle variable for subsequent storage of the NVS handle. For related descriptions, please refer to Non-Volatile Storage Library.Call
nvs_open()
to get the NVS handle of the specified namespace for reading and writing operations on its key-value pairs. For related usage and parameter descriptions, please refer to Non-Volatile Storage Library.
..note:
When obtaining a handle, if the specified namespace does not exist, ``nvs_open()`` will automatically create this namespace in the default partition and return the access handle; if the namespace already exists, it will directly return its access handle.
Data Reading and Writing
Integer Value Reading and Writing:
Call
nvs_set_i32()
to write an integer value into the cache of the specified namespace. For related usage and parameter descriptions, please refer to Non-Volatile Storage Library.Call
nvs_get_i32()
to read the integer value corresponding to the specified key in the specified namespace. For related usage and parameter descriptions, please refer to Non-Volatile Storage Library.
String Reading and Writing:
Invoke
nvs_set_str()
to write a string into the cache of a specified namespace. For usage and parameter details, refer to Non-Volatile Storage.Invoke
nvs_get_str()
to read the string value corresponding to the specified key in the specified namespace. For usage and parameter details, refer to Non-Volatile Storage. During the reading process, this function needs to be called twice, respectively for:
Obtaining the actual length of the target string in NVS (including the ending
\0
), so as to dynamically allocate sufficient memory.Obtaining the actual string data and saving it to the allocated memory, ensuring the data is complete and safe.
..note:
When invoking ``nvs_set_*()`` to write data, the data is not immediately written into the flash memory, but is first stored in the cache in RAM or the data structure managed by NVS. This can reduce flash write operations, extend flash life, and improve write efficiency.
Query NVS Key Value
Use an iterator to traverse all keys under a specified namespace and perform corresponding operations as needed. For specific instructions, see NVS Iterator.
Delete NVS Key Value
Invoke
nvs_erase_key()
to delete a specified key. For usage and parameter details, refer to Non-Volatile Storage.
Commit Changes
Invoke
nvs_commit()
to submit changes, ensuring that changes to NVS are written into flash storage. For usage and parameter details, refer to Non-Volatile Storage.
..note:
Write all data previously written through ``nvs_set_*()`` into flash memory to ensure data persistence. If ``nvs_commit()`` is not invoked, even if the program ends or power is cut off, the data in RAM will not be saved to flash memory, and the write will be lost.
Close NVS Handle
Invoke
nvs_close()
to close the NVS handle and release resources. For usage and parameter details, refer to Non-Volatile Storage.