警告
This document is not updated for ESP32H21 yet, so some of the content may not be correct.
This warning was automatically inserted due to the source file being in the add_warnings_pages list.
在引导程序中使用 NVS
概述
本指南概述了可用于自定义引导加载程序代码的 NVS(非易失性存储)功能及其限制。
由于引导加载程序运行环境的限制,自定义引导加载程序代码无法直接使用完整的 NVS API。为此,NVS 提供了一个简化 API,仅支持只读访问 NVS 数据。
该 API 支持读取除 blob 之外的所有 NVS 数据类型。一次 API 调用可以同时读取多个 NVS 条目。可以从同一 NVS 分区的不同命名空间读取值,读取结果存储在输入/输出结构数组中,每个数据项的固定大小最多为 8 字节。
由于引导加载程序中的堆内存分配限制,读取字符串条目时,API 要求调用者提供缓冲区及其大小。
读取加密的 NVS 分区
如果 NVS 分区使用 NVS 加密 指南中的加密方案,该 API 还支持解密 NVS 数据。
应用程序应按照以下步骤使用 nvs_bootloader_read() API 读取加密 NVS 分区数据:
根据所选的 NVS 加密方案填充 NVS 安全配置结构
nvs_sec_cfg_t(详情请参阅 NVS 加密)。使用
nvs_bootloader_read_security_cfg()API 从指定的安全方案中读取 NVS 安全配置。获取安全配置后,使用
nvs_bootloader_secure_init()API 初始化 NVS flash 分区。使用
nvs_bootloader_read()API 执行 NVS 读取操作。使用
nvs_bootloader_secure_deinit()API 反初始化 NVS flash 分区,并清除安全配置。
备注
在使用基于 HMAC 的方案进行上述流程时,可以直接调用 nvs_flash_secure_init() API 对默认和自定义 NVS 分区进行加密,而无需启用 NVS 加密相关配置选项(如 CONFIG_NVS_ENCRYPTION, CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME -> CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC, CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID)。
应用示例
代码示例请参阅 ESP-IDF 示例 storage/nvs 目录下的 storage/nvs/nvs_bootloader。
本节演示了如何在输入/输出结构中准备数据,以支持不同的数据类型、命名空间和键。此外,还包含从 NVS 读取字符串数据的示例。
示例还演示了如何检查读取操作是否成功,数据是否存在不一致,或是否在 NVS 中找不到某些值的情形。该示例能够将 API 返回的值(或错误码)打印到控制台。
API 参考
Header File
This header file can be included with:
#include "nvs_bootloader.h"
This header file is a part of the API provided by the
nvs_flashcomponent. To declare that your component depends onnvs_flash, add the following to your CMakeLists.txt:REQUIRES nvs_flash
or
PRIV_REQUIRES nvs_flash
Functions
-
esp_err_t nvs_bootloader_read(const char *partition_name, const size_t read_list_count, nvs_bootloader_read_list_t read_list[])
Reads data specified from the specified NVS partition.
This function reads data from the NVS partition specified by
partition_name. Multiple NVS entries can be read in a single call. The list of entries to read is specified in theread_listarray. Function indicates overall success or failure by its return value. In case it is ESP_OK or ESP_ERR_INVALID_ARG, result of validation / reading of individual entry is returned in theresult_codemember of each element of theread_listarray.- 参数:
partition_name -- The name of the NVS partition to read from.
read_list_count -- The number of elements in the
read_listarray.read_list -- An array of
nvs_bootloader_read_list_tstructures specifying the keys and buffers for reading data.
- 返回:
The return value of the function in this file can be one of the following:
ESP_OK: The function successfully checked all input parameters and executed successfully. The individualresult_codeinread_listindicates the result of the lookup for a particular requested key.ESP_ERR_INVALID_ARG: The validity of allread_listinput parameters was checked and failed for at least one of the parameters. The individualresult_codeinread_listprovides the detailed reason. This error code is also returned when read_list is null or read_list_count is 0.ESP_ERR_NVS_INVALID_NAME: The partition name specified is too long or is null.ESP_ERR_NVS_PART_NOT_FOUND: The partition was not found in the partition table.ESP_ERR_NVS_CORRUPT_KEY_PART: Encryption-related problems.ESP_ERR_NVS_WRONG_ENCRYPTION: Encryption-related problems.ESP_ERR_INVALID_STATE: NVS partition or pages related errors - wrong size of partition, header inconsistent / entries inconsistencies, multiple active pages, page in state INVALID.ESP_ERR_NO_MEM: Cannot allocate memory required to perform the function.Technical errors in underlying storage.
-
esp_err_t nvs_bootloader_secure_init(const nvs_sec_cfg_t *sec_cfg)
Initialize internal NVS security context, thus, enabling the NVS bootloader read API to decrypt encrypted NVS partitions.
备注
Once
nvs_bootloader_secure_init()is performed,nvs_bootloader_read()can correctly read only those NVS partitions that are encrypted using the givennvs_sec_cfg_tsecurity config, untilnvs_bootloader_secure_deinit()clears the internal NVS security context.- 参数:
sec_cfg -- NVS security key that would be used for decrypting the NVS partition
- 返回:
ESP_OK if security initialization is successful
-
void nvs_bootloader_secure_deinit(void)
Clear the internal NVS security context.
-
esp_err_t nvs_bootloader_read_security_cfg(nvs_sec_scheme_t *scheme_cfg, nvs_sec_cfg_t *cfg)
Reads NVS bootloader security configuration set by the specified security scheme.
- 参数:
scheme_cfg -- [in] Security scheme specific configuration
cfg -- [out] Security configuration (encryption keys)
- 返回:
ESP_OK, if cfg was read successfully;
ESP_ERR_INVALID_ARG, if scheme_cfg or cfg is NULL;
ESP_FAIL, if the key reading process fails
Unions
-
union nvs_bootloader_value_placeholder_t
- #include <nvs_bootloader.h>
Union of value placeholders for all nvs_type_t supported by bootloader code.
Public Members
-
uint8_t u8_val
Placeholder for unsigned 8 bit integer variable
-
int8_t i8_val
Placeholder for signed 8 bit integer variable
-
uint16_t u16_val
Placeholder for unsigned 16 bit integer variable
-
int16_t i16_val
Placeholder for signed 16 bit integer variable
-
uint32_t u32_val
Placeholder for unsigned 32 bit integer variable
-
int32_t i32_val
Placeholder for signed 32 bit integer variable
-
uint64_t u64_val
Placeholder for unsigned 64 bit integer variable
-
int64_t i64_val
Placeholder for signed 64 bit integer variable
-
float float_val
Placeholder for IEEE 754 single precision float variable
-
double double_val
Placeholder for IEEE 754 double precision float variable
-
nvs_bootloader_str_value_placeholder_t str_val
Placeholder for string buffer information
-
uint8_t u8_val
Structures
-
struct nvs_bootloader_str_value_placeholder_t
Placeholders for buffer pointer and length of string type.
-
struct nvs_bootloader_read_list_t
Structure representing one NVS bootloader entry.
This structure serves as read operation input parameters and result value and status placeholder. Before calling the
nvs_bootloader_readfunction, populate the namespace_name, key_name and value_type members. If string value has to be read, provide also buffer and its length in thevalue.str_valmember.The result_code member will be populated after calling the
nvs_bootloader_readfunction. There are 2 possible situations and interpretations depending on he result_code returned by thenvs_bootloader_read:If the return value of the
nvs_bootloader_readwas ESP_OK, the result_code will be one of the following:ESP_OK: Entry found, value member contains the data. This is the only case when the value member is populated.ESP_ERR_NVS_TYPE_MISMATCH: Entry was found, but requested datatype doesn't match datatype found in NVSESP_ERR_NVS_NOT_FOUND: Data was not found.ESP_ERR_INVALID_SIZE: the value found for string is longer than the space provided in placeholder (str_val.buff_len)
If the return value of the
nvs_bootloader_readwas ESP_ERR_INVALID_ARG, the result_code will be one of the following:ESP_ERR_NVS_NOT_FOUND: Check of this parameters was successful.ESP_ERR_NVS_INVALID_NAME: namespace_name is NULL or too longESP_ERR_NVS_KEY_TOO_LONG: key_name NULL or too longESP_ERR_INVALID_SIZE: the size of the buffer provided for NVS_TYPE_STR in placeholder (str_val.buff_len) is zero or exceeds maximum value NVS_CONST_STR_LEN_MAX_SIZEESP_ERR_INVALID_ARG: Invalid datatype requested
Public Members
-
const char *namespace_name
Input. Namespace of the entry
-
const char *key_name
Input. Key of the entry
-
nvs_type_t value_type
Input. Expected datatype to be read, can be any of NVS_TYPE_U*, NVS_TYPE_I*, NVS_TYPE_FLOAT, NVS_TYPE_DOUBLE or NVS_TYPE_STR
-
esp_err_t result_code
Output. Result code of this entry. Explanation is in general description of the struct nvs_bootloader_read_list_t
-
nvs_bootloader_value_placeholder_t value
Input/Output. Placeholder for value read
-
uint8_t namespace_index
Output. Index of the namespace (internal variable, do not use)