Merge branch 'refactor/nvs_iterator_api' into 'master'
NVS: New interface for iterator functions Closes IDFGH-6149 See merge request espressif/esp-idf!18081
This commit is contained in:
@@ -55,11 +55,12 @@ Iterators allow to list key-value pairs stored in NVS, based on specified partit
|
||||
|
||||
There are the following functions available:
|
||||
|
||||
- :cpp:func:`nvs_entry_find` returns an opaque handle, which is used in subsequent calls to the :cpp:func:`nvs_entry_next` and :cpp:func:`nvs_entry_info` functions.
|
||||
- :cpp:func:`nvs_entry_next` returns iterator to the next key-value pair.
|
||||
- :cpp:func:`nvs_entry_find` creates an opaque handle, which is used in subsequent calls to the :cpp:func:`nvs_entry_next` and :cpp:func:`nvs_entry_info` functions.
|
||||
- :cpp:func:`nvs_entry_next` advances an iterator to the next key-value pair.
|
||||
- :cpp:func:`nvs_entry_info` returns information about each key-value pair
|
||||
|
||||
If none or no other key-value pair was found for given criteria, :cpp:func:`nvs_entry_find` and :cpp:func:`nvs_entry_next` return NULL. In that case, the iterator does not have to be released. If the iterator is no longer needed, you can release it by using the function :cpp:func:`nvs_release_iterator`.
|
||||
In general, all iterators obtained via :cpp:func:`nvs_entry_find` have to be released using :cpp:func:`nvs_release_iterator`, which also tolerates ``NULL`` iterators.
|
||||
:cpp:func:`nvs_entry_find` and :cpp:func:`nvs_entry_next` will set the given iterator to ``NULL`` or a valid iterator in all cases except a parameter error occured (i.e., return ``ESP_ERR_NVS_NOT_FOUND``). In case of a parameter error, the given iterator will not be modified. Hence, it is best practice to initialize the iterator to ``NULL`` before calling :cpp:func:`nvs_entry_find` to avoid complicated error checking before releasing the iterator.
|
||||
|
||||
|
||||
Security, tampering, and robustness
|
||||
|
||||
@@ -18,3 +18,52 @@ esp_vfs_semihost_register() signature change
|
||||
--------------------------------------------
|
||||
|
||||
New signature is ``esp_err_t esp_vfs_semihost_register(const char* base_path);`` Absolute path as a second parameter will no longer in use. Instead, the OpenOCD command ``ESP_SEMIHOST_BASEDIR`` should be used to set the full path on the host.
|
||||
|
||||
NVS
|
||||
---
|
||||
|
||||
``nvs_entry_find()``, ``nvs_entry_next()`` and ``nvs_entry_info()`` always return ``esp_err_t`` now instead of ``void`` or ``nvs_iterator_t``. This provides better error reporting when parameters are invalid or something goes wrong internally than returning ``nullptr`` instead of a valid iterator or checking parameters with ``assert``. ``nvs_entry_find()`` and ``nvs_entry_next()`` modify iterators via parameters now instead of returning an iterator.
|
||||
|
||||
The old programming pattern to iterate over an NVS partition was as follows:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
nvs_iterator_t it = nvs_entry_find(<nvs_partition_name>, <namespace>, NVS_TYPE_ANY);
|
||||
while (it != NULL) {
|
||||
nvs_entry_info_t info;
|
||||
nvs_entry_info(it, &info);
|
||||
it = nvs_entry_next(it);
|
||||
printf("key '%s', type '%d' \n", info.key, info.type);
|
||||
};
|
||||
|
||||
The new programming pattern to iterate over an NVS partition is now:
|
||||
|
||||
.. highlight:: c
|
||||
|
||||
::
|
||||
|
||||
nvs_iterator_t it = nullptr;
|
||||
esp_err_t res = nvs_entry_find(<nvs_partition_name>, <namespace>, NVS_TYPE_ANY, &it);
|
||||
while(res == ESP_OK) {
|
||||
nvs_entry_info_t info;
|
||||
nvs_entry_info(it, &info); // Can omit error check if parameters are guaranteed to be non-NULL
|
||||
printf("key '%s', type '%d' \n", info.key, info.type);
|
||||
res = nvs_entry_next(&it);
|
||||
}
|
||||
nvs_release_iterator(it);
|
||||
|
||||
Signature Changes
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
``nvs_iterator_t nvs_entry_find(const char *part_name, const char *namespace_name, nvs_type_t type)`` changes to ``esp_err_t nvs_entry_find(const char *part_name, const char *namespace_name, nvs_type_t type, nvs_iterator_t *output_iterator)``. The iterator is returned via the parameter ``output_iterator`` instead of a return value. This allows reporting additional errors, like e.g. memory errors, via the new return value.
|
||||
|
||||
``nvs_iterator_t nvs_entry_next(nvs_iterator_t iterator)`` changes to ``esp_err_t nvs_entry_next(nvs_iterator_t *it)``. This allows reporting parameter errors and internal errors, like e.g. flash errors.
|
||||
|
||||
``void nvs_entry_info(nvs_iterator_t iterator, nvs_entry_info_t *out_info)`` changes to ``esp_err_t nvs_entry_info(const nvs_iterator_t iterator, nvs_entry_info_t *out_info)`` to allow reporting parameter errors.
|
||||
|
||||
Iterator Validity
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Note that due to the new signatures, it is possible to have an invalid iterator from ``nvs_entry_find()``, if there is a parameter errors. Hence, it is important to initialize the iterator with ``NULL`` before using ``nvs_entry_find()`` to avoid complex error checking before calling ``nvs_release_iterator()``. A good example is the programming pattern above.
|
||||
|
||||
@@ -55,11 +55,12 @@ NVS 迭代器
|
||||
|
||||
您可以使用以下函数,执行相关操作:
|
||||
|
||||
- ``nvs_entry_find``:返回一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数;
|
||||
- ``nvs_entry_next``:返回指向下一个键值对的迭代器;
|
||||
- ``nvs_entry_find``:创建一个不透明句柄,用于后续调用 ``nvs_entry_next`` 和 ``nvs_entry_info`` 函数;
|
||||
- ``nvs_entry_next``:让迭代器指向下一个键值对;
|
||||
- ``nvs_entry_info``:返回每个键值对的信息。
|
||||
|
||||
如果未找到符合标准的键值对,``nvs_entry_find`` 和 ``nvs_entry_next`` 将返回 NULL,此时不必释放迭代器。若不再需要迭代器,可使用 ``nvs_release_iterator`` 释放迭代器。
|
||||
总的来说,所有通过 :cpp:func:`nvs_entry_find` 获得的迭代器(包括 ``NULL`` 迭代器)都必须使用 :cpp:func:`nvs_release_iterator` 释放。
|
||||
一般情况下,:cpp:func:`nvs_entry_find` 和 :cpp:func:`nvs_entry_next` 会将给定的迭代器设置为 ``NULL`` 或为一个有效的迭代器。但如果出现参数错误(如返回 ``ESP_ERR_NVS_NOT_FOUND``),给定的迭代器不会被修改。因此,在调用 :cpp:func:`nvs_entry_find` 之前最好将迭代器初始化为 ``NULL``,这样可以避免在释放迭代器之前进行复杂的错误检查。
|
||||
|
||||
|
||||
安全性、篡改性及鲁棒性
|
||||
@@ -168,7 +169,7 @@ ESP-IDF :example:`storage` 目录下提供了数个代码示例:
|
||||
|
||||
:example:`storage/nvs_rw_blob`
|
||||
|
||||
演示如何读取及写入 NVS 单个整数值和 Blob(二进制大对象),并在 NVS 中存储这一数值,即便 {IDF_TARGET_NAME} 模组重启也不会消失。
|
||||
演示如何读取及写入 NVS 单个整数值和 BLOB(二进制大对象),并在 NVS 中存储这一数值,即便 {IDF_TARGET_NAME} 模组重启也不会消失。
|
||||
|
||||
* value - 记录 {IDF_TARGET_NAME} 模组软重启次数和硬重启次数。
|
||||
* blob - 内含记录模组运行次数的表格。此表格将被从 NVS 读取至动态分配的 RAM 上。每次手动软重启后,表格内运行次数即增加一次,新加的运行次数被写入 NVS。下拉 GPIO0 即可手动软重启。
|
||||
@@ -177,7 +178,7 @@ ESP-IDF :example:`storage` 目录下提供了数个代码示例:
|
||||
|
||||
:example:`storage/nvs_rw_value_cxx`
|
||||
|
||||
这个例子与 :example:`storage/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 处理类。
|
||||
这个例子与 :example:`storage/nvs_rw_value` 完全一样,只是使用了 C++ 的 NVS 句柄类。
|
||||
|
||||
内部实现
|
||||
---------
|
||||
|
||||
Reference in New Issue
Block a user