config_manager_example

Example of the component espressif/esp_config_manager v0.5.0
# ESP Config Manager 简单例程

- [English Version](./README.md)
- 例程难度:⭐

## 例程简介

本例程演示如何使用 `esp_config_manager` 在持久化介质中保存多个应用配置组。例程会在首次启动时加载默认值,保存修改后的配置,再次读取并打印每个配置的来源。

本例程展示了双槽配置存储、默认值合并、带 CRC 校验的配置记录、可选加解密钩子,以及 NVS、SPIFFS、raw flash 分区等存储介质的绑定方式。

### 典型场景

本例程适用于需要可靠本地配置保存的产品,例如音频参数、启动计数、网络相关标志位,以及需要兼容结构体扩展的配置升级场景。

### 运行机制

1. 初始化 NVS;当选择 filesystem 存储方式时,同时初始化 SPIFFS。
2. 创建 audio、lifecycle、net 三个独立配置组。
3. 将每个配置组绑定到选定的存储介质。
4. 调用 `esp_config_manager_load()` 读取配置。
5. 修改每个配置组中的一个字段,调用 `esp_config_manager_save()` 保存,再次读取验证持久化结果。
6. 释放 manager handle 并打印 `Done`。

## 环境配置

### 硬件要求

- ESP-IDF 支持的 Espressif 开发板,例如 ESP32 或 ESP32-S3。

### 默认 IDF 分支

本例程支持 ESP-IDF release/v5.5 及以后的分支,ADF 仓库默认使用 ESP-IDF release/v5.5 分支。

## 编译和下载

### 编译准备

编译本例程前需先确保已配置 ESP-IDF 环境。若未配置,请在 ESP-IDF 根目录运行以下脚本:

```
./install.sh
. ./export.sh
```

进入本例程工程目录:

```
cd $ADF_PATH/components/esp_config_manager/examples/simple
```

### 项目配置

默认存储方式为 NVS:

```c
#define EXAMPLE_CFG_STORAGE_BACKEND  EXAMPLE_STORAGE_NVS
```

如需测试其他存储方式,可修改 `main/config_manager_example.c` 中的 `EXAMPLE_CFG_STORAGE_BACKEND`:

- `EXAMPLE_STORAGE_NVS`:每个配置组使用独立 NVS namespace。
- `EXAMPLE_STORAGE_FS`:primary 和 backup 文件保存到 `/spiffs`,使用 `partitions.csv` 中的 `storage` SPIFFS 分区。
- `EXAMPLE_STORAGE_FLASH`:primary 和 backup 数据分别保存到 `partitions.csv` 中定义的 raw data 分区。

`sdkconfig.defaults` 已启用自定义分区表,可满足 SPIFFS 和 raw flash 存储演示所需的分区配置。

如需运行较完整的自测流程,可在 `main/config_manager_example.c` 中设置:

```c
#define CFG_EX_RUN_SELFTEST  1
```

### 编译与烧录

- 编译示例程序:

```
idf.py build
```

- 烧录程序并运行 monitor 工具来查看串口输出(替换 `PORT` 为端口名称):

```
idf.py -p PORT flash monitor
```

- 退出调试界面使用 `Ctrl-]`。

## 如何使用例程

### 功能和用法

烧录后例程会自动运行。首次启动时,各配置组会从默认值加载并写入存储;后续启动时会优先从 primary 存储槽读取,并在上次保存值的基础上继续变化。

默认 NVS 存储方式会保留已保存数据。如需重新观察首次启动的默认值恢复流程,可在烧录前执行 `idf.py erase-flash`。

### 日志输出

以下日志片段展示默认 NVS 存储方式下的普通演示流程:

```c
I (325) CFG_MANAGER_EXAMPLE: Storage backend: NVS (3 config groups)
I (345) CFG_MANAGER_EXAMPLE: [audio] from defaults repair=0
I (345) CFG_MANAGER_EXAMPLE:   vol=42 flags=0x00000001 profile=default bri=80 lvl=10 array=esp1
I (355) CFG_MANAGER_EXAMPLE: [audio] from primary repair=0
I (355) CFG_MANAGER_EXAMPLE:   vol=43 flags=0x00000001 profile=default bri=80 lvl=0 array=esp1
I (365) CFG_MANAGER_EXAMPLE: --- group audio done ---
I (375) CFG_MANAGER_EXAMPLE: [lifecycle] from defaults — boot_count=0 session_flags=0x0100
I (375) CFG_MANAGER_EXAMPLE:   array=esp2
I (385) CFG_MANAGER_EXAMPLE: [lifecycle] from primary — boot_count=1 session_flags=0x0100
I (395) CFG_MANAGER_EXAMPLE: --- group lifecycle done ---
I (405) CFG_MANAGER_EXAMPLE: [net] from defaults — route_tag=0 if=sta0 mtu=1500
I (415) CFG_MANAGER_EXAMPLE: [net] from primary — route_tag=305419896 if=sta0 mtu=1500
I (425) CFG_MANAGER_EXAMPLE: --- group net done ---
I (425) CFG_MANAGER_EXAMPLE: Done
```

开启 self-test 模式后,关键日志如下:

```c
I (325) CFG_MANAGER_EXAMPLE: ======== selftest start (backend=NVS, 3 groups) ========
I (345) CFG_MANAGER_EXAMPLE: [TEST] g0.packed_layout PASS
I (365) CFG_MANAGER_EXAMPLE: [TEST] g0.load_defaults_after_wipe PASS — ESP_OK
I (385) CFG_MANAGER_EXAMPLE: [TEST] g0.save_load_roundtrip PASS — ESP_OK
I (405) CFG_MANAGER_EXAMPLE: [TEST] g0.fallback_to_backup_crc PASS — ESP_OK
I (425) CFG_MANAGER_EXAMPLE: [TEST] g0.primary_repaired_after_load PASS — ESP_OK
I (445) CFG_MANAGER_EXAMPLE: [TEST] g0.merge_tail_new_fields PASS
I (465) CFG_MANAGER_EXAMPLE: ======== selftest end ========
```

## 故障排除

### SPIFFS 或 raw flash 存储加载失败

请确认构建时已使用 `sdkconfig.defaults`,并启用了自定义 `partitions.csv`。这两种存储方式需要 `storage`、`cfg_pri`、`cfg_bak`、`cfg2_pri`、`cfg2_bak`、`cfg3_pri`、`cfg3_bak` 等分区。

### 重新烧录后配置值没有恢复默认值

普通应用烧录不会清除 NVS 数据。如需清除已保存的配置数据,可执行:

```
idf.py erase-flash
```

### self-test 日志出现 `FAIL`

可先执行 `idf.py erase-flash` 后重新测试。如果使用 flash 存储方式,请同时确认自定义分区表已生效,且 `partitions.csv` 中的每个 raw config 分区都存在。

## 技术支持

请按照下面的链接获取技术支持:

- 技术支持参见 [esp32.com](https://esp32.com/viewforum.php?f=20) 论坛
- 问题反馈与功能需求,请创建 [GitHub issue](https://github.com/espressif/esp-adf/issues)

我们会尽快回复。

To create a project from this example, run:

idf.py create-project-from-example "espressif/esp_config_manager=0.5.0:config_manager_example"

or download archive (~11.92 KB)