| 支持的芯片 | ESP32-S3 | ESP32-P4 | ESP32-C5 |
| :--------: | :------: | :------: | :------: |
|            |    ✅     |    ✅     |    ✅     |

# NVS 服务示例

[English Version](./README.md)

本示例演示了如何使用 ESP-Brookesia 的 NVS(非易失性存储)服务进行数据存储和读取操作。示例展示了基本操作、类型安全操作、命名空间管理和错误处理等功能。

## 📑 目录

- [NVS 服务示例](#nvs-服务示例)
  - [📑 目录](#-目录)
  - [✨ 功能特性](#-功能特性)
  - [🚩 快速入门](#-快速入门)
    - [硬件要求](#硬件要求)
    - [开发环境](#开发环境)
  - [🔨 编译烧录](#-编译烧录)
  - [🚀 快速体验](#-快速体验)
  - [📖 示例说明](#-示例说明)
    - [基本操作演示](#基本操作演示)
    - [类型安全操作演示](#类型安全操作演示)
    - [命名空间管理演示](#命名空间管理演示)
    - [错误处理演示](#错误处理演示)
  - [🔍 故障排除](#-故障排除)
    - [NVS 初始化失败](#nvs-初始化失败)
    - [数据读取失败](#数据读取失败)
    - [值验证失败](#值验证失败)
  - [💬 技术支持与反馈](#-技术支持与反馈)

## ✨ 功能特性

- 💾 **基本操作**:支持键值对的设置(`Set`)、获取(`Get`)、列表(`List`)和删除(`Erase`)
- 🔒 **类型安全**:提供类型安全的 API,支持多种数据类型的自动序列化/反序列化
- 📦 **多种数据类型**:支持基本类型(`bool`、`int32_t`、`uint8_t`、`int16_t`)和复杂类型(`string`、`int64_t`、`uint64_t`、`float`、`double`、`vector`、复杂结构体等)
- 🗂️ **命名空间管理**:支持多个命名空间,实现数据隔离和管理
- ✅ **值验证**:自动验证读取的值是否与写入的值一致,确保数据完整性
- ⚠️ **错误处理**:演示如何处理不存在的键和类型不匹配等错误情况

## 🚩 快速入门

### 硬件要求

**基础功能**:搭载 `ESP32-S3`、`ESP32-P4` 或 `ESP32-C5` 芯片且 `Flash >= 4MB` 的开发板

### 开发环境

- ESP-IDF `v5.5.2` TAG(推荐)或 `release/v5.5` 分支

## 🔨 编译烧录

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

按 `Ctrl-]` 退出串口监视。

## 🚀 快速体验

固件烧录成功后,设备会自动运行示例程序。您可以通过串口监视器查看以下演示:

1. **基本操作演示**:展示如何使用 Set、Get、List、Erase 函数进行基本的键值对操作
2. **类型安全操作演示**:展示如何使用类型安全的 API 存储和读取各种数据类型
3. **命名空间管理演示**:展示如何使用多个命名空间进行数据隔离
4. **错误处理演示**:展示如何处理各种错误情况

所有演示都会自动验证读取的值是否与写入的值一致,确保数据完整性。

## 📖 示例说明

### 基本操作演示

演示了 NVS 服务的通用 API,包含四个基本操作:

- **Set(设置)**:批量设置多个键值对(字符串、整数、布尔值)
- **List(列表)**:列出命名空间中所有的键值对及其类型
- **Get(获取)**:获取指定的键值对,并验证值与设置的值一致
- **Erase(删除)**:删除指定的键值对,并验证删除结果

### 类型安全操作演示

演示了如何使用类型安全的 `save_key_value` 和 `get_key_value` API 处理各种数据类型:

**直接存储类型**(无需序列化):

- `bool`:布尔值
- `int32_t`:32 位有符号整数
- `uint8_t`、`int16_t`:小整数类型(≤32 位)

**序列化存储类型**(需要序列化):

- `std::string`:字符串
- `int64_t`、`uint64_t`:大整数类型(>32 位)
- `float`、`double`:浮点数
- `std::vector<int>`:整数向量
- `ComplexStruct`:复杂结构体(包含字符串、整数、布尔值、浮点数、向量、结构体嵌套等)

所有类型都会自动进行序列化/反序列化,并在读取后验证值的正确性。

> [!NOTE]
> 相较于使用通用的 RPC-style API 进行数据存储和读取,建议使用类型安全的 API 进行数据存储和读取,因为它们更容易使用且更不容易出错。

### 命名空间管理演示

演示了如何使用多个命名空间进行数据隔离:

- 在不同的命名空间(`storage`、`config`、`stats`)中存储相同键名的数据
- 从不同命名空间中读取数据,验证数据隔离
- 列出每个命名空间中的所有条目

### 错误处理演示

演示了如何处理常见的错误情况:

- **不存在的键**:尝试获取不存在的键,展示错误信息
- **类型不匹配**:尝试以错误的类型读取数据,展示类型不匹配错误

## 🔍 故障排除

### NVS 初始化失败

确保分区表中已正确配置 NVS 分区。检查 `partitions.csv` 文件,确保包含 NVS 分区定义。

### 数据读取失败

- 检查键名是否正确
- 检查命名空间是否正确
- 检查数据类型是否匹配
- 查看串口日志中的错误信息

### 值验证失败

如果值验证失败,可能的原因:

- 数据类型不匹配
- 序列化/反序列化问题
- NVS 存储损坏

查看串口日志中的详细错误信息,检查写入和读取的值。

## 💬 技术支持与反馈

请通过以下渠道进行反馈:

- 有关功能请求或错误报告,请创建新的 [GitHub 问题](https://github.com/espressif/esp-brookesia/issues)

我们会尽快回复。

To create a project from this example, run:

idf.py create-project-from-example "espressif/brookesia_service_nvs=0.7.3:nvs"

or download archive (~13.22 KB)