【ESP32】打造全网最强esp-idf基础教程——13.ESP32中的NVS

ESP32中的NVS

       这几天的天气只有钱包的余额能让我冷静,好好活着,每天都有新的打击,写写博客压压惊。

一、什么是NVS?
       NVS即Non-volatile storage,意思是非易失存储,也就是掉电后能依然能持久化保存数据。在我们应用NVS时,一般用于存储一些配置数据、状态数据等,一般不会用来存储存放大量的数据量。

       在嵌入式系统中,NVS主要是在flash进行键值对的存储。那么什么是键值对?这边举一个例子方便大家理解,假设我们要把东西存到flash中,按照底层的操作习惯,我们要先指定一个地址,然后对这个地址执行擦除操作,然后才能写入;读取的时候也需要根据这个地址,然后指定读取长度。如果我们要存的项比较多,又在代码中比较分散,我们对flash的地址就很难管理。因为我们很难知道要存的内容与其他地址有没冲突,会不会误擦除。存在诸多问题。那如果有一个机制,方便帮我们把这些检测判断活都干了,不需要我们指定地址操作,那岂不是很好。有的人又说了,文件系统不就是这样吗?是的,文件系统是这样,但NVS操作更加轻量级。

       在NVS中,我们要存一个值,我们不需要指定地址,但需要指定一个“键”,我们称为key,然后我们在这个“键”索引下存我们的值,也就是value。假设我们要存wifi的ssid和密码,我们可以在nvs中这样定义。

       key = ssid,value = testwifi

       key = password,value = 12345678
在键名ssid下,我们存的值是testwifi,在键名password下,我们存的值是12345678。因此键名key一般不会修改,经常修改的是value。

       在ESP32中对于NVS的操作,还需要指定一个命名空间,是因为还考虑了一种情况,在各个不同的功能模块中,键名是有可能取到一样的,比如对于wifi模块,存在一个password键名,对于管理员模块,可能也存在一个password键名,这样有可能就造成了重复,程序无法按我们的意思进行。如果我们增加了一个命名空间进行隔离,那么键名有重复也不怕,比如说在wifi模块中,我们指定一个命名空间”wifi”,在此命名空间下有ssid和password键名,在管理员模块,我们指定一个命名空间”manager”,在此命名空间下有password键名,这两组命名空间互不干扰。

二、ESP32中NVS的使用
       上一节介绍了NVS的基本概念,这一节我们看下esp-idf中给我们提供了什么接口。
//打开一个NVS存储操作

       esp_err_t nvs_open(const char* namespace_name, /*命名空间名称*/
       nvs_open_mode_t open_mode,  /* 打开的模式*/

                                                           NVS_READONLY,只读
                                                        &

<think> 我们正在讨论的是ESP32-S3在ESP-IDF环境下使用`esp_timer.h`头文件所需的组件。根据ESP-IDF的文档和组件结构,`esp_timer`是ESP-IDF的核心组件之一,通常默认包含在项目中,不需要额外添加组件依赖。但是,为了完整性,我们可以查看其依赖关系。 在ESP-IDF中,`esp_timer`组件提供了高分辨率的软件定时器,它依赖于以下组件: - `freertos`:提供RTOS基础功能。 - `soc`:提供与芯片相关的底层支持。 - `hal`:硬件抽象层。 然而,在用户代码中直接包含`#include "esp_timer.h"`时,通常只需要在`CMakeLists.txt`文件中声明对`esp_timer`组件的依赖即可。由于`esp_timer`是公共组件,它会被自动包含在大多数项目中。 ### 解决方案 1. **确认组件依赖**:在项目的`CMakeLists.txt`文件中,确保`REQUIRES`或`PRIV_REQUIRES`部分包含`esp_timer`。例如: ```cmake idf_component_register(SRCS "main.c" INCLUDE_DIRS "." REQUIRES esp_timer) ``` 实际上,即使不显式添加,因为`main`组件默认不依赖其他组件,所以需要显式添加`esp_timer`。但在很多情况下,如果你使用了其他组件(比如`console`、`nvs_flash`等),它们可能已经间接依赖了`esp_timer`,所以可能不需要显式添加。但为了确保,最好显式添加。 2. **检查Kconfig配置**:`esp_timer`组件有一些配置选项,可以通过`menuconfig`进行配置。这些选项位于: ``` Component config ---> ESP System Settings ---> esp_timer ---> ``` 3. **代码示例**:以下是一个简单的使用`esp_timer`的示例: ```c #include <stdio.h> #include "esp_timer.h" void app_main(void) { // 创建一个周期为1秒的定时器 const esp_timer_create_args_t periodic_timer_args = { .callback = &timer_callback, .name = "periodic" }; esp_timer_handle_t periodic_timer; esp_timer_create(&periodic_timer_args, &periodic_timer); esp_timer_start_periodic(periodic_timer, 1000000); // 1秒 // 其他代码... } ``` ### 总结 在ESP-IDF项目中使用`esp_timer.h`头文件,需要在项目的`CMakeLists.txt`文件中添加对`esp_timer`组件的依赖,即: ```cmake REQUIRES esp_timer ``` 这样,编译系统就会链接`esp_timer`组件,并包含其头文件路径。 ### 相关问题 1. 如何配置`esp_timer`的高分辨率特性? 2. `esp_timer`与FreeRTOS定时器有何区别? 3. 如何测量代码执行时间使用`esp_timer`? 4. 如何停止和删除`esp_timer`定时器? </think> 在 ESP32-S3 的 ESP-IDF 开发环境中,使用 `#include "esp_timer.h"` **不需要额外添加组件**。`esp_timer` 是 ESP-IDF 的核心组件,已经包含在默认框架中。以下是详细说明: ### 使用步骤: 1. **在代码中直接包含头文件**: ```c #include "esp_timer.h" ``` 无需修改任何组件配置即可使用。 2. **在 CMakeLists.txt 中声明依赖**(标准项目已自动包含): ```cmake idf_component_register(SRCS "main.c" INCLUDE_DIRS "." REQUIRES esp_timer) # 此处声明依赖关系 ``` 3. **验证组件状态**: 运行 `idf.py menuconfig` 查看: ``` Component config ---> ESP System Settings ---> [*] High-resolution timer (esp_timer) ``` 默认已启用 ✅ ### 关键特性说明: 1. **高精度定时**: - 分辨率可达 1μs(使用 RTC 或主 XTAL 时钟源) - 支持单次定时 (`esp_timer_start_once()`) 和周期定时 (`esp_timer_start_periodic()`) 2. **自动包含依赖**: - `esp_timer` 组件会自动引入依赖项: - `freertos`(任务调度) - `soc`(外设控制) - `esp_common`(通用 API) 3. **使用示例**: ```c static void timer_callback(void* arg) { ESP_LOGI("TIMER", "Triggered"); } void app_main() { esp_timer_create_args_t timer_args = { .callback = &timer_callback, .name = "my_timer" }; esp_timer_handle_t timer; esp_timer_create(&timer_args, &timer); esp_timer_start_once(timer, 3 * 1000000); // 3秒定时 } ``` ### 常见问题排查: 如果编译报错 `undefined reference to esp_timer...`: 1. 检查 CMakeLists.txt 是否包含 `REQUIRES esp_timer` 2. 确认 ESP-IDF 版本 ≥ v4.0(旧版本可能需要手动启用) 3. 运行 `idf.py reconfigure` 刷新配置 > 📌 **注意**:虽然不需要额外组件,但使用深度睡眠功能时需要启用 `CONFIG_ESP_TIMER_DYNAMIC` 配置项: > ```kconfig > Component config ---> > ESP System Settings ---> > [*] Enable dynamic esp_timer allocation > ``` ### 参考文档: - [ESP-IDF 编程指南 - 高分辨率定时器](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-reference/system/esp_timer.html)[^1] - [esp_timer API 头文件](https://github.com/espressif/esp-idf/blob/master/components/esp_timer/include/esp_timer.h)[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值