diff --git a/components/nvs_flash/include/nvs_handle.hpp b/components/nvs_flash/include/nvs_handle.hpp index 2fe9ad98682..c50681857af 100644 --- a/components/nvs_flash/include/nvs_handle.hpp +++ b/components/nvs_flash/include/nvs_handle.hpp @@ -70,13 +70,14 @@ public: * For strings, the maximum length (including null character) is * 4000 bytes, if there is one complete page free for writing. * This decreases, however, if the free space is fragmented. - * Note that enums loose their type information when stored in NVS. Ensure that the correct - * enum type is used during retrieval with \ref get_item! + * Note that enums lose their type information when stored in NVS. Ensure that the correct + * enum type is used during retrieval with get_item. * * @return * - ESP_OK if value was set successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid * - 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_KEY_TOO_LONG if key name exceeds the maximum length * - 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 @@ -84,11 +85,31 @@ public: * 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 + * - other error codes from the underlying storage driver */ template esp_err_t set_item(const char *key, T value); - virtual - esp_err_t set_string(const char *key, const char* value) = 0; + + /** + * @brief set string for given key + * + * @param[in] key Key name. Maximal length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. + * @param[in] value The string to set. Maximum length (including null character) is 4000 bytes, + * if there is one complete page free for writing. + * + * @return + * - ESP_OK if value was set successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only + * - ESP_ERR_NVS_KEY_TOO_LONG if key name exceeds the maximum length + * - 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 + * - ESP_ERR_NVS_VALUE_TOO_LONG if the string value is too long + * - other error codes from the underlying storage driver + */ + virtual esp_err_t set_string(const char *key, const char* value) = 0; /** * @brief get value for given key @@ -102,13 +123,15 @@ public: * @param[in] key Key name. Maximal length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. * @param value The output value. All integral types which are declared in ItemType as well as enums * are allowed. Note however that enums lost their type information when stored in NVS. - * Ensure that the correct enum type is used during retrieval with \ref get_item! + * Ensure that the correct enum type is used during retrieval with get_item. * * @return * - ESP_OK if the value was retrieved successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist - * - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints + * - ESP_ERR_NVS_TYPE_MISMATCH if the stored value type does not match the requested type * - ESP_ERR_NVS_INVALID_LENGTH if length is not sufficient to store data + * - other error codes from the underlying storage driver */ template esp_err_t get_item(const char *key, T &value); @@ -127,8 +150,9 @@ public: * * @return * - ESP_OK if value was set successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid * - 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_KEY_TOO_LONG if key name exceeds the maximum length * - 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 @@ -136,39 +160,58 @@ public: * 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 value is too long + * - other error codes from the underlying storage driver * - * @note compare to \ref nvs_set_blob in nvs.h + * @note compare to nvs_set_blob() in nvs.h */ virtual esp_err_t set_blob(const char *key, const void* blob, size_t len) = 0; /** - * @brief get value for given key + * @brief get string value for given key * - * These functions retrieve the data of an entry, given its key. If key does not + * Retrieves the string data of an entry, given its key. If key does not * exist, or the requested variable type doesn't match the type which was used * when setting a value, an error is returned. * - * In case of any error, out_value is not modified. - * - * Both functions expect out_value to be a pointer to an already allocated variable - * of the given type. - * - * It is suggested that nvs_get/set_str is used for zero-terminated short C strings, and - * nvs_get/set_blob is used for arbitrary data structures and long C strings. + * In case of any error, out_str is not modified. * * @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. - * @param out_str/ Pointer to the output value. - * out_blob - * @param[inout] len The length of the output buffer pointed to by out_str/out_blob. - * Use \c get_item_size to query the size of the item beforehand. + * @param[out] out_str Pointer to the output string buffer. + * @param[in] len The length of the output buffer pointed to by out_str. + * Use get_item_size to query the size of the item beforehand. * * @return * - ESP_OK if the value was retrieved successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist - * - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints + * - ESP_ERR_NVS_TYPE_MISMATCH if the stored value type does not match the requested type * - ESP_ERR_NVS_INVALID_LENGTH if length is not sufficient to store data + * - other error codes from the underlying storage driver */ virtual esp_err_t get_string(const char *key, char* out_str, size_t len) = 0; + + /** + * @brief get blob value for given key + * + * Retrieves the binary data of an entry, given its key. If key does not + * exist, or the requested variable type doesn't match the type which was used + * when setting a value, an error is returned. + * + * In case of any error, out_blob is not modified. + * + * @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. + * @param[out] out_blob Pointer to the output blob buffer. + * @param[in] len The length of the output buffer pointed to by out_blob. + * Use get_item_size to query the size of the item beforehand. + * + * @return + * - ESP_OK if the value was retrieved successfully + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist + * - ESP_ERR_NVS_TYPE_MISMATCH if the stored value type does not match the requested type + * - ESP_ERR_NVS_INVALID_LENGTH if length is not sufficient to store data + * - other error codes from the underlying storage driver + */ virtual esp_err_t get_blob(const char *key, void* out_blob, size_t len) = 0; /** @@ -179,9 +222,12 @@ public: * @param[out] size Size of the item, if it exists. * For strings, this size includes the zero terminator. * - * @return - ESP_OK if the item with specified type and key exists. Its size will be returned via \c size. - * - ESP_ERR_NVS_NOT_FOUND if an item with the requested key and type doesn't exist or any other - * error occurs. + * @return + * - ESP_OK if the item with specified type and key exists. Its size will be returned via size. + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_NOT_FOUND if an item with the requested key and type doesn't exist + * - ESP_ERR_NVS_TYPE_MISMATCH if the stored value type does not match the requested type + * - other error codes from the underlying storage driver */ virtual esp_err_t get_item_size(ItemType datatype, const char *key, size_t &size) = 0; @@ -189,61 +235,112 @@ public: * @brief Checks whether key exists and optionally returns also data type of associated entry. * * @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. - * @param[out] nvstype Nvs data type to of entry, if it exists. + * @param[out] nvstype Nvs data type of entry, if it exists. * - * @return - ESP_OK if NVS entry for key provided was found. Data type will be returned via \c nvstype. - * - 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_FAIL if there is an internal error; most likely due to corrupted - * NVS partition (only if NVS assertion checks are disabled). - * - other error codes from the underlying storage driver. + * @return + * - ESP_OK if NVS entry for key provided was found. Data type will be returned via nvstype. + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist + * - ESP_FAIL if there is an internal error; most likely due to corrupted + * NVS partition (only if NVS assertion checks are disabled) + * - other error codes from the underlying storage driver */ virtual esp_err_t find_key(const char* key, nvs_type_t &nvstype) = 0; /** * @brief Erases an entry. + * + * @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty. + * + * @return + * - ESP_OK if erase operation was successful + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only + * - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist + * - other error codes from the underlying storage driver */ virtual esp_err_t erase_item(const char* key) = 0; /** - * Erases all entries in the scope of this handle. The scope may vary, depending on the implementation. + * @brief Erases all entries in the scope of this handle. * - * @not If you want to erase the whole nvs flash (partition), refer to \ref + * The scope may vary, depending on the implementation (typically the opened namespace). + * + * @note If you want to erase the whole NVS flash partition, use nvs_flash_erase() / + * nvs_flash_erase_partition() instead. + * + * @return + * - ESP_OK if erase operation was successful + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only + * - other error codes from the underlying storage driver */ virtual esp_err_t erase_all() = 0; /** - * Purges all erased entries in the scope of this handle. The scope may vary, depending on the implementation. + * @brief Purges all erased entries in the scope of this handle. + * + * The scope may vary, depending on the implementation. + * + * @return + * - ESP_OK if purge operation was successful + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only + * - other error codes from the underlying storage driver */ virtual esp_err_t purge_all() = 0; /** - * Commits all changes done through this handle so far. + * @brief Commits all changes done through this handle so far. + * * Currently, NVS writes to storage right after the set and get functions, * but this is not guaranteed. + * + * @return + * - ESP_OK if commit was successful + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid + * - other error codes from the underlying storage driver */ virtual esp_err_t commit() = 0; /** * @brief Calculate all entries in the scope of the handle. * - * @param[out] used_entries Returns amount of used entries from a namespace on success. - * + * @param[out] usedEntries Returns amount of used entries from a namespace on success. * * @return - * - ESP_OK if the changes have been written successfully. - * Return param used_entries will be filled valid value. + * - ESP_OK if usedEntries was filled with a valid value + * - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is invalid * - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized. - * Return param used_entries will be filled 0. - * - ESP_ERR_INVALID_ARG if nvs_stats equal to NULL. - * - Other error codes from the underlying storage driver. - * Return param used_entries will be filled 0. + * Return param usedEntries will be filled with 0. + * - other error codes from the underlying storage driver. + * Return param usedEntries will be filled with 0. */ virtual esp_err_t get_used_entry_count(size_t& usedEntries) = 0; protected: + /** + * @brief Set an item of a given datatype. + * + * @param[in] datatype Item data type. + * @param[in] key Key name. + * @param[in] data Pointer to the value to store. + * @param[in] dataSize Size of the value in bytes. + * + * @return esp_err_t result codes matching set_item / set_blob. + */ virtual esp_err_t set_typed_item(ItemType datatype, const char *key, const void* data, size_t dataSize) = 0; + /** + * @brief Get an item of a given datatype. + * + * @param[in] datatype Item data type. + * @param[in] key Key name. + * @param[out] data Pointer to the output buffer. + * @param[in] dataSize Size of the output buffer in bytes. + * + * @return esp_err_t result codes matching get_item / get_blob. + */ virtual esp_err_t get_typed_item(ItemType datatype, const char *key, void* data, size_t dataSize) = 0; }; @@ -253,16 +350,23 @@ protected: * The handle is automatically closed on destruction. The scope of the handle is the namespace ns_name * in a particular partition partition_name. * The parameters partition_name, ns_name and open_mode have the same meaning and restrictions as the parameters - * part_name, name and open_mode in \ref nvs_open_from_partition, respectively. + * part_name, namespace_name and open_mode in nvs_open_from_partition(), respectively. * - * @param err an optional pointer to an esp_err_t result of the open operation, having the same meaning as the return - * value in \ref nvs_open_from_partition: + * @param[in] partition_name Label of the NVS partition to open. + * @param[in] ns_name Namespace name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. + * @param[in] open_mode NVS_READONLY, NVS_READWRITE, or NVS_READWRITE_PURGE. + * @param[out] err Optional pointer to an esp_err_t result of the open operation, having the same meaning + * as the return value of nvs_open_from_partition(): * - ESP_OK if storage handle was opened successfully + * - ESP_ERR_INVALID_ARG if partition_name or ns_name is NULL * - 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 + * - ESP_ERR_NVS_PART_NOT_FOUND if the partition with the specified name is not found + * - ESP_ERR_NVS_NOT_FOUND if namespace doesn't exist yet and * mode is NVS_READONLY - * - ESP_ERR_NVS_INVALID_NAME if namespace name doesn't satisfy constraints + * - ESP_ERR_NVS_KEY_TOO_LONG if namespace name exceeds the maximum length + * - ESP_ERR_NO_MEM if memory could not be allocated for the internal structures + * - ESP_ERR_NVS_NOT_ENOUGH_SPACE if there is no space for a new entry or there are too many different + * namespaces (maximum allowed different namespaces: 254) * - ESP_ERR_NOT_ALLOWED if the NVS partition is read-only and mode is NVS_READWRITE * - other error codes from the underlying storage driver * @@ -274,8 +378,28 @@ std::unique_ptr open_nvs_handle_from_partition(const char *partition_ esp_err_t *err = nullptr); /** - * @brief This function does the same as \ref open_nvs_handle_from_partition but uses the default nvs partition + * @brief Open NVS handle from the default NVS partition. + * + * This function does the same as open_nvs_handle_from_partition() but uses the default nvs partition * instead of a partition_name parameter. + * + * @param[in] ns_name Namespace name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. + * @param[in] open_mode NVS_READONLY, NVS_READWRITE, or NVS_READWRITE_PURGE. + * @param[out] err Optional pointer to an esp_err_t result of the open operation: + * - ESP_OK if storage handle was opened successfully + * - ESP_ERR_INVALID_ARG if ns_name is NULL + * - 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 if namespace doesn't exist yet and + * mode is NVS_READONLY + * - ESP_ERR_NVS_KEY_TOO_LONG if namespace name exceeds the maximum length + * - ESP_ERR_NO_MEM if memory could not be allocated for the internal structures + * - ESP_ERR_NVS_NOT_ENOUGH_SPACE if there is no space for a new entry or there are too many different + * namespaces (maximum allowed different namespaces: 254) + * - ESP_ERR_NOT_ALLOWED if the NVS partition is read-only and mode is NVS_READWRITE + * - other error codes from the underlying storage driver + * + * @return unique pointer of an nvs handle on success, an empty unique pointer otherwise */ std::unique_ptr open_nvs_handle(const char *ns_name, nvs_open_mode_t open_mode, diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 29b16cb209b..27ea222396d 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -340,6 +340,7 @@ INPUT = \ $(PROJECT_PATH)/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \ $(PROJECT_PATH)/components/nvs_flash/include/nvs.h \ + $(PROJECT_PATH)/components/nvs_flash/include/nvs_handle.hpp \ $(PROJECT_PATH)/components/nvs_flash/include/nvs_bootloader.h \ $(PROJECT_PATH)/components/nvs_sec_provider/include/nvs_sec_provider.h \ $(PROJECT_PATH)/components/openthread/include/esp_openthread_border_router.h \ diff --git a/docs/en/api-reference/storage/nvs_flash.rst b/docs/en/api-reference/storage/nvs_flash.rst index 0d4aac34c57..27058ce9c23 100644 --- a/docs/en/api-reference/storage/nvs_flash.rst +++ b/docs/en/api-reference/storage/nvs_flash.rst @@ -86,6 +86,22 @@ The open mode parameter controls the access level and security behavior: Namespaces with the same name in different NVS partitions are considered as separate namespaces. +C++ API +^^^^^^^ + +In addition to the C API described above, NVS provides a C++ class interface in :component_file:`nvs_flash/include/nvs_handle.hpp` (namespace ``nvs``). + +Use ``nvs::open_nvs_handle()`` or ``nvs::open_nvs_handle_from_partition()`` to open a namespace. These functions return a ``std::unique_ptr``. The handle is closed automatically when the unique pointer is destroyed (RAII), so there is no need to call a separate close function. + +``nvs::NVSHandle`` provides methods that mirror the C API, including: + +- ``set_item`` / ``get_item`` — typed get/set for integral, floating-point, and enum types +- ``set_string`` / ``get_string`` — string values +- ``set_blob`` / ``get_blob`` — binary blob values +- ``commit``, ``erase_item``, ``erase_all``, ``purge_all``, ``find_key``, and related helpers + +Open modes (``NVS_READONLY``, ``NVS_READWRITE``, ``NVS_READWRITE_PURGE``) and key/namespace constraints are the same as for the C API. See the :ref:`API Reference ` below for full class and function documentation, and :example:`storage/nvs/nvs_rw_value_cxx` for a complete example. + NVS Iterators ^^^^^^^^^^^^^ @@ -264,7 +280,7 @@ You can find code examples in the :example:`storage/nvs` directory of ESP-IDF ex :example:`storage/nvs/nvs_rw_value_cxx` - This example does exactly the same as :example:`storage/nvs/nvs_rw_value`, except that it uses the C++ NVS handle class. + This example does exactly the same as :example:`storage/nvs/nvs_rw_value`, except that it uses the C++ NVS handle class (``nvs::NVSHandle`` via ``nvs::open_nvs_handle()``). :example:`storage/nvs/nvs_statistics` @@ -552,9 +568,13 @@ At build time the mode NVS will use for accessing its underlying storage can be +.. _nvs-api-reference: + API Reference ------------- .. include-build-file:: inc/nvs_flash.inc .. include-build-file:: inc/nvs.inc + +.. include-build-file:: inc/nvs_handle.inc diff --git a/docs/zh_CN/api-reference/storage/nvs_flash.rst b/docs/zh_CN/api-reference/storage/nvs_flash.rst index 7a85231adf2..e0e0195cb71 100644 --- a/docs/zh_CN/api-reference/storage/nvs_flash.rst +++ b/docs/zh_CN/api-reference/storage/nvs_flash.rst @@ -86,6 +86,22 @@ open mode 参数控制访问级别和安全行为: 在不同的 NVS 分区中,同名的命名空间被视为相互独立的命名空间。 +C++ API +^^^^^^^ + +除上文所述的 C API 外,NVS 还在 :component_file:`nvs_flash/include/nvs_handle.hpp` 中提供了 C++ 类接口(命名空间 ``nvs``)。 + +使用 ``nvs::open_nvs_handle()`` 或 ``nvs::open_nvs_handle_from_partition()`` 打开命名空间。这些函数返回 ``std::unique_ptr``。当该智能指针被销毁时,句柄会自动关闭(RAII),因此无需另行调用关闭函数。 + +``nvs::NVSHandle`` 提供与 C API 对应的方法,包括: + +- ``set_item`` / ``get_item`` — 面向整型、浮点型和枚举类型的类型化读写 +- ``set_string`` / ``get_string`` — 字符串值 +- ``set_blob`` / ``get_blob`` — 二进制 blob 值 +- ``commit``、``erase_item``、``erase_all``、``purge_all``、``find_key`` 及相关辅助方法 + +打开模式(``NVS_READONLY``、``NVS_READWRITE``、``NVS_READWRITE_PURGE``)以及键名/命名空间约束与 C API 相同。完整的类与函数说明见下文 :ref:`API 参考 `,完整示例见 :example:`storage/nvs/nvs_rw_value_cxx`。 + NVS 迭代器 ^^^^^^^^^^^^^ @@ -264,7 +280,7 @@ ESP-IDF :example:`storage/nvs` 目录下提供了数个代码示例: :example:`storage/nvs/nvs_rw_value_cxx` - 这个例子与 :example:`storage/nvs/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 句柄类。 + 这个例子与 :example:`storage/nvs/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 句柄类(通过 ``nvs::open_nvs_handle()`` 获取 ``nvs::NVSHandle``)。 :example:`storage/nvs/nvs_statistics` @@ -552,9 +568,13 @@ NVS 正常运行所需的默认最小空间为 12 KiB (``0x3000``),即至少 +.. _nvs-api-reference: + API 参考 ------------- .. include-build-file:: inc/nvs_flash.inc .. include-build-file:: inc/nvs.inc + +.. include-build-file:: inc/nvs_handle.inc