ESP32存储blog笔记

发布者:温柔心绪最新更新时间:2025-09-10 来源: cnblogs关键字:ESP32 手机看文章 扫描二维码
随时随地手机看文章

基于ESP-IDF4.1


  1 #include

  2 #include 'freertos/FreeRTOS.h'

  3 #include 'freertos/task.h'

  4 #include 'esp_system.h'

  5 #include 'nvs_flash.h'

  6 #include 'nvs.h'

  7 #include 'driver/gpio.h'

  8 

  9 #define STORAGE_NAMESPACE 'storage'

 10 

 11 

 12 //保存设备重启数

 13 esp_err_t save_restart_counter(void)

 14 {

 15     nvs_handle_t my_handle;

 16     esp_err_t err;

 17 

 18     // 打开

 19     err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);

 20     if (err != ESP_OK) return err;

 21 

 22     // 读取

 23     int32_t restart_counter = 0; 

 24     err = nvs_get_i32(my_handle, 'restart_conter', &restart_counter);

 25     if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

 26 

 27     // 写入

 28     restart_counter++;

 29     err = nvs_set_i32(my_handle, 'restart_conter', restart_counter);

 30     if (err != ESP_OK) return err;

 31 

 32     // 提交写入的值

 33     err = nvs_commit(my_handle);

 34     if (err != ESP_OK) return err;

 35 

 36     // 关闭

 37     nvs_close(my_handle);

 38     return ESP_OK;

 39 }

 40 

 41 /* Save new run time value in NVS

 42    by first reading a table of previously saved values

 43    and then adding the new value at the end of the table.

 44    Return an error if anything goes wrong

 45    during this process.

 46  */

 47 esp_err_t save_run_time(void)

 48 {

 49     nvs_handle_t my_handle;

 50     esp_err_t err;

 51 

 52     // 打开

 53     err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);

 54     if (err != ESP_OK) return err;

 55 

 56     // 读取内存空间大小

 57     size_t required_size = 0;  // value will default to 0, if not set yet in NVS

 58     err = nvs_get_blob(my_handle, 'run_time', NULL, &required_size);

 59     if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

 60 

 61     // 读取之前保存的blob

 62     uint32_t* run_time = malloc(required_size + sizeof(uint32_t));

 63     if (required_size > 0) {

 64         err = nvs_get_blob(my_handle, 'run_time', run_time, &required_size);

 65         if (err != ESP_OK) {

 66             free(run_time);

 67             return err;

 68         }

 69     }

 70 

 71     // 写入值,包含之前保存的blob

 72     required_size += sizeof(uint32_t);

 73     run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS;

 74     err = nvs_set_blob(my_handle, 'run_time', run_time, required_size);

 75     free(run_time);

 76 

 77     if (err != ESP_OK) return err;

 78 

 79     // 提交

 80     err = nvs_commit(my_handle);

 81     if (err != ESP_OK) return err;

 82 

 83     // 关闭

 84     nvs_close(my_handle);

 85     return ESP_OK;

 86 }

 87 

 88 

 89 //从NVS读取和打印重启计数和运行时表

 90 esp_err_t print_what_saved(void)

 91 {

 92     nvs_handle_t my_handle;

 93     esp_err_t err;

 94 

 95     // 打开

 96     err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);

 97     if (err != ESP_OK) return err;

 98 

 99     // 读取重启数

100     int32_t restart_counter = 0; // NVS没有设置值时需要设置默认值0

101     err = nvs_get_i32(my_handle, 'restart_conter', &restart_counter);

102     if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

103     printf('Restart counter = %dn', restart_counter);

104 

105     // 读取运行时blob

106     size_t required_size = 0;  

107     //获取内存空间存储从NVS读取的blob

108     err = nvs_get_blob(my_handle, 'run_time', NULL, &required_size);

109     if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

110     printf('Run time:n');

111     if (required_size == 0) {

112         printf('Nothing saved yet!n');

113     } else {

114         //malloc和free是申请内存空间与释放内存空间的函数

115         uint32_t* run_time = malloc(required_size);

116         err = nvs_get_blob(my_handle, 'run_time', run_time, &required_size);

117         if (err != ESP_OK) {

118             free(run_time);

119             return err;

120         }

121         for (int i = 0; i < required_size / sizeof(uint32_t); i++) {

122             printf('%d: %dn', i + 1, run_time[i]);

123         }

124         free(run_time);

125     }

126 

127     // 关闭

128     nvs_close(my_handle);

129     return ESP_OK;

130 }

131 

132 

133 void app_main(void)

134 {

135     esp_err_t err = nvs_flash_init();

136     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {

137         // NVS分区被截断,需要擦除并重新初始化

138         ESP_ERROR_CHECK(nvs_flash_erase());

139         err = nvs_flash_init();

140     }

141     ESP_ERROR_CHECK( err );

142 

143     err = print_what_saved();

144     if (err != ESP_OK) printf('Error (%s) reading data from NVS!n', esp_err_to_name(err));

145 

146     err = save_restart_counter();

147     if (err != ESP_OK) printf('Error (%s) saving restart counter to NVS!n', esp_err_to_name(err));

148 

149     gpio_pad_select_gpio(GPIO_NUM_0);

150     gpio_set_direction(GPIO_NUM_0, GPIO_MODE_DEF_INPUT);

151 

152     // 读取GPIO0状态,低电平超过一秒则保存运行时并重启

153     while (1) {

154         if (gpio_get_level(GPIO_NUM_0) == 0) {

155             vTaskDelay(1000 / portTICK_PERIOD_MS);

156             if(gpio_get_level(GPIO_NUM_0) == 0) {

157                 err = save_run_time();

158                 if (err != ESP_OK) printf('Error (%s) saving run time blob to NVS!n', esp_err_to_name(err));

159                 printf('Restarting...n');

160                 fflush(stdout);

161                 esp_restart();

162             }

163         }

164         vTaskDelay(200 / portTICK_PERIOD_MS);

165     }

166 }


关键字:ESP32 引用地址:ESP32存储blog笔记

上一篇:ESP32使用SPIFFS文件系统笔记
下一篇:ESP32非易失性存储整型数据笔记

推荐阅读最新更新时间:2026-03-20 12:23

ESP32与STM32:性能对比分析及选型指南
一、核心架构对比 1.1 ESP32 – 无线物联网霸主 // 典型双核架构配置 #include freertos/FreeRTOS.h #include freertos/task.h void app_main() { // 核心0执行无线通信任务 xTaskCreatePinnedToCore(wifi_task, WiFi , 4096, NULL, 5, NULL, 0); // 核心1执行用户逻辑 xTaskCreatePinnedToCore(user_task, User , 4096, NULL, 5, NULL, 1); } 核心架构:Xtensa LX6双核处理器(主频240MHz)
[单片机]
ESP32高分辨率计时器笔记
尽管FreeRTOS提供了软件计时器,但这些计时器有一些限制: 最大分辨率等于RTOS滴答周期 计时器回调从低优先级任务分派 硬件计时器不受这两个限制,但是通常它们使用起来不太方便。例如,应用组件可能需要定时器事件在将来的特定时间触发,但是硬件定时器仅包含一个用于中断产生的“比较”值。这意味着需要在硬件计时器之上构建一些功能来管理挂起事件列表,以便在发生相应的硬件中断时可以调度这些事件的回调。 esp_timer 一组API提供了一次性的计时器和定期的计时器,微秒级的时间分辨率以及64位范围。 基于ESP-IDF4.1 1 #include stdio.h 2 #include string.h 3 #
[单片机]
长按短按控制LED灯-ESP32中断处理
#include stdio.h #include string.h #include stdlib.h #include freertos/FreeRTOS.h #include freertos/task.h #include freertos/queue.h #include driver/gpio.h #include sys/time.h typedef enum { KEY_SHORT_PRESS = 1, KEY_LONG_PRESS =2, } alink_key_t; #define GPIO_LED_IO 13 #define GPIO_LED_PIN_SEL 1ULL GPI
[单片机]
ESP32构建系统(CMake版)
ESP32 芯片是一款 2.4 GHz Wi-Fi 和蓝牙双模芯片,内置 1 或 2 个 32 位处理器,运算能力最高可达 600 DMIPS。 ESP-IDF 即乐鑫物联网开发框架,可为在 Windows、Linux 和 macOS 系统平台上开发 ESP32 应用程序提供工具链、API、组件和工作流的支持。 概述: 一个 ESP-IDF 项目可以看作是多个不同组件的集合,ESP-IDF 可以显式地指定和配置每个组件。在构建项目的时候,构建系统会前往 ESP-IDF 目录、项目目录和用户自定义目录(可选)中查找所有组件,允许用户通过文本菜单系统配置 ESP-IDF 项目中用到的每个组件。在所有组件配置结束后,构建系统开始
[单片机]
<font color='red'>ESP32</font>构建系统(CMake版)
API调用小记(Touchdesigner和ESP32
调用 调用网络API通常是通过HTTP来做的,对于TD这种上位机软件来说,可以直接选择GET、POST这些方式,通过地址传入参数。一般的形式是地址后面加'?'然后跟参数名=值,不同的参数之间通过‘&’连接,例如 地址?参数名1=值1&参数名2=值2...... 例如调用心知天气的API,可以查到官方的文档是这样的 TD 所以在TD可以新建一个web client,在URL填入 https://api.seniverse.com/v3/weather/now.json ,方法选择GET 然后新建一个table在里面按照文档说明写入参数,传入OP里 点request就可以获取了,TD会自动用上面提到
[单片机]
关于ESP32/8266使用async-mqtt-client库的一些基本介绍
1. 前期准备 因为async-mqtt-client使用异步,会额外依赖异步库 对于ESP32核心的,依赖me-no-dev/AsyncTCP (ESP32) 8266的芯片依赖me-no-dev/ESPAsyncTCP (ESP8266) 需要额外下载对应的库,并放入依赖路径下 另外,本文主要阐述如何在ESP32中的使用 8266用法基本类似,仅在WiFi连接和计时器TimerHandle有接口区别,所以不会进行详细叙述 2. 使用介绍 先打开async-mqtt-client库中的文件夹examples,找到案例 这里选择ESP32的案例FullyFeatured-ESP32.ino 案例的前面一段都是具体的方法,直
[单片机]
ESP32 开发环境和基本使用
Linux (Ubuntu) 默认软件包安装: sudo apt-get install git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0 获取 ESP-IDF mkdir -p ~/esp cd ~/esp git clone --recursive https://github.com/espressif/esp-idf.git 获取工具链 cd ~/esp/esp-idf ./instal
[单片机]
解决方法:ESP32同时打开蓝牙、WIFI和OTA后程序过大导致无法启动
一、问题 使用 ESP32-WROOM-32E(4MB) 模组,同时使用了蓝牙模块、WIFI模块功能,编译的时候没问题,然后运行的时候报以下错误: 二、原因 ESP32 如果使同时使用了蓝牙模块、WIFI模块和OTA的话很有可能会导致程序过大(超过1M),系统无法启动的情况。这里提供一种通过修改分区表扩大程序储存空间的方法来避免这一问题。这一解决方法同样只用于因为其他问题导致的程序过大的情况。 三、解决方法 3.1 分区表 每片 ESP32 的 Flash 可以包含多个应用程序,以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储器数据等)。因此,引入分区表的概念。 具体来说,ESP32 在 Flash 的 默认偏移
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved