ESP32存储blog笔记
基于ESP-IDF4.1
1 #include <stdio.h>
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 = %d\n", 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: %d\n", 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 }
原文:https://gitee.com/EspressifSystems/esp-idf
ESP32存储blog笔记的更多相关文章
- Web客户端数据存储学习笔记——Cookie
今天对登录访问的安全以及web客户端存储做了一些大致的学习,决定在这方面加深理解,记录在博客里.第一个接触到的是Cookie... WHAT? WHY? HOW? 在学习cookie的使用时发现其名称 ...
- ios 存储学习笔记
一.主要路径: Library/Caches/此文件用于存储那些需要及可延迟或重创建的临时数据.且这些内容不会被IOS 系统备份,特别地,当设备磁盘空间不足且应用不在运行状态时,IOS 系统可能会移除 ...
- Kudu存储实战笔记
有人会问,为啥要用这个叫啥Kudu的,Kudu是啥? 就像官网所说,Kudu是一个针对Apache hadoop 平台而开发的列式存储管理器,在本菜鸟看来,它是一种介于hdfs与hbase的一种存储. ...
- HTML5新增的本地存储功能(笔记)
HTML5新增的本地存储功能分为两种,分别对应两个JS对象:①本地存储对应localStorage对象,主要用于长期保存整个网站的数据(这些数据可以永久保存在客户端电脑硬盘内).②会话存储对应sess ...
- iOS数据存储简要笔记
1. 数据存储常用的方式 (1)XML 属性列表(plist)归档 (2)preference(偏好设置) (3)NSKeyedArchiver归档(NSCoding) (4) SQLite3 ...
- 《FFT家族—从不会到崩溃(坑)》读blog笔记
免责声明 原文地址https://blog.csdn.net/linjiayang2016/article/details/80341958,作者linjiayang2016.\text{linjia ...
- MySQL技术内幕 InnoDB存储引擎(笔记)
1. InnoDB 体系架构 其中,后台程序主要负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据. 此外将已经修改的数据刷新到磁盘文件,同时保证在数据库发生异常的时候Innodb能恢复正常 ...
- Microsoft SQL Server 2005技术内幕:存储引擎笔记
http://www.cnblogs.com/lyhabc/articles/3942053.html
- ESP32高分辨率计时器笔记
尽管FreeRTOS提供了软件计时器,但这些计时器有一些限制: 最大分辨率等于RTOS滴答周期 计时器回调从低优先级任务分派 硬件计时器不受这两个限制,但是通常它们使用起来不太方便.例如,应用组件可能 ...
随机推荐
- Psexec和wmiexec的原理和区别
PSEXEC 针对远程建立连接的方式有两种,一种先建立IPC通道连接,然后直接使用,操作如下: net use \\192.168.0.1\ipc$ "password" /use ...
- java 常见OPTS参数的含义
1. -XX:MaxPermSize=256m -XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配 2. java.awt.headless Headless模式是系统的 ...
- 手把手带你快速入门jQuery(视频|资料,建议收藏!)
jQuery是什么? jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架). jQuery设计的宗旨是 ...
- Single Shot Multibox Detection (SSD)实战(下)
Single Shot Multibox Detection (SSD)实战(下) 2. Training 将逐步解释如何训练SSD模型进行目标检测. 2.1. Data Reading and In ...
- 利用UltraScale和UltraScale+FPGA和MPSOC加速DSP设计生产力
利用UltraScale和UltraScale+FPGA和MPSOC加速DSP设计生产力 Accelerating DSP Design Productivity with UltraScale an ...
- Django基础之模型层(02)
1 重要概念 # 多表查询 """ 正向查询 反向查询 当前查询对象是否含有外键字段 如果有就是正向 没有无则是反向 口诀: 正向查询按外键字段 多对多需要额外再加一个. ...
- NOIP模拟测试28「阴阳·虎·山洞」
写这几个题解我觉得我就像在按照官方题解抄一样 阴阳 题解 将题目中给的阴阳看作黑色和白色 首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减 类似这样 否则不满足这个条件 但合法染色方 ...
- 创建react项目并集成eslint/prettier/commit-lint
创建 react 项目 npx create-react-app jira-new --template typescript 如果不想使用 TS,而要用 JS 的话,则删除 -template ty ...
- Java进阶 | Proxy动态代理机制详解
一.Jvm加载对象 在说Java动态代理之前,还是要说一下Jvm加载对象的过程,这个依旧是理解动态代理的基础性原理: Java类即源代码程序.java类型文件,经过编译器编译之后就被转换成字节代码.c ...
- external-attacher源码分析(1)-main方法与启动参数分析
更多 ceph-csi 其他源码分析,请查看下面这篇博文:kubernetes ceph-csi分析目录导航 摘要 ceph-csi分析-external-attacher源码分析.external- ...