基于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笔记的更多相关文章

  1. Web客户端数据存储学习笔记——Cookie

    今天对登录访问的安全以及web客户端存储做了一些大致的学习,决定在这方面加深理解,记录在博客里.第一个接触到的是Cookie... WHAT? WHY? HOW? 在学习cookie的使用时发现其名称 ...

  2. ios 存储学习笔记

    一.主要路径: Library/Caches/此文件用于存储那些需要及可延迟或重创建的临时数据.且这些内容不会被IOS 系统备份,特别地,当设备磁盘空间不足且应用不在运行状态时,IOS 系统可能会移除 ...

  3. Kudu存储实战笔记

    有人会问,为啥要用这个叫啥Kudu的,Kudu是啥? 就像官网所说,Kudu是一个针对Apache hadoop 平台而开发的列式存储管理器,在本菜鸟看来,它是一种介于hdfs与hbase的一种存储. ...

  4. HTML5新增的本地存储功能(笔记)

    HTML5新增的本地存储功能分为两种,分别对应两个JS对象:①本地存储对应localStorage对象,主要用于长期保存整个网站的数据(这些数据可以永久保存在客户端电脑硬盘内).②会话存储对应sess ...

  5. iOS数据存储简要笔记

    1.  数据存储常用的方式 (1)XML 属性列表(plist)归档 (2)preference(偏好设置) (3)NSKeyedArchiver归档(NSCoding) (4)  SQLite3   ...

  6. 《FFT家族—从不会到崩溃(坑)》读blog笔记

    免责声明 原文地址https://blog.csdn.net/linjiayang2016/article/details/80341958,作者linjiayang2016.\text{linjia ...

  7. MySQL技术内幕 InnoDB存储引擎(笔记)

    1. InnoDB 体系架构 其中,后台程序主要负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据. 此外将已经修改的数据刷新到磁盘文件,同时保证在数据库发生异常的时候Innodb能恢复正常 ...

  8. Microsoft SQL Server 2005技术内幕:存储引擎笔记

    http://www.cnblogs.com/lyhabc/articles/3942053.html

  9. ESP32高分辨率计时器笔记

    尽管FreeRTOS提供了软件计时器,但这些计时器有一些限制: 最大分辨率等于RTOS滴答周期 计时器回调从低优先级任务分派 硬件计时器不受这两个限制,但是通常它们使用起来不太方便.例如,应用组件可能 ...

随机推荐

  1. nginx 配置 conf stream

    nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx支持四层负载均衡.默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream参数 ...

  2. Java核心技术卷阅读随笔--第4章【对象与类】

    对 象 与 类 4.1 面向对象程序设计概述 面向对象程序设计(简称 OOP) 是当今主流的程序设计范型, 它已经取代了 20 世纪 70 年代的" 结构化" 过程化程序设计开发技 ...

  3. 解决了一个java服务线程退出的问题

    问题背景 ​ 早上才上班,测试就提了一个问题:"昨天所有批量任务都没有跑".我看了一下任务监控页面,任务是有生成的,但却一直在等待调度状态.初步怀疑是我们的调度服务问题,于是上去查 ...

  4. Python+Selenium学习笔记3 - 二维码生成

    用qrcode模块生成二维码 # coding = utf-8 import qrcode qr = qrcode.QRCode( version=1, error_correction=qrcode ...

  5. zk客户端及锁的使用

    1.生成zk客户端对象 private CuratorFramework buildClient() { logger.info("zookeeper registry center ini ...

  6. OpenCV读写图像文件解析

    OpenCV读写图像文件解析 imdecode 从内存中的缓冲区读取图像. C++:Mat imdecode(InputArray buf, int flags) C++:Mat imdecode(I ...

  7. Hash源码注释解析

    部分代码注释解析: 1 import java.io.IOException; 2 import java.io.InvalidObjectException; 3 import java.io.Se ...

  8. OpenCV开发实战1——抖音哈哈镜效果

    前言 在抖音中,我们经常看到各种抖音玩家都喜欢使用哈哈镜效果.那么什么是哈哈镜呢? 在现实生活中,哈哈镜是指一种表面凹凸不平的镜子,可以反应出人像及物体的扭曲面貌.简单点来说就是拉伸人脸(物件),或者 ...

  9. 深度解密:Java与线程的关系

    并发不一定要依赖多线程(如PHP的多进程并发),但在Java中谈论并发,大多数都与线程脱不开关系. 线程的实现 线程是CPU调度的基本单位,Thread类与大部分的Java API有显著的差别,它的所 ...

  10. NOIP模拟测试29「爬山·学数数·七十和十七」

    爬山题解不想写了 学数数 离散化然后找到以每一个值为最大值的连续子段有多少个,然后开个桶维护 那么怎么找以每一个值为最大值的连续子段个数 方法1(我的极笨的方法) 考试时我的丑陋思路, 定义极左值为左 ...