【快速上手ESP32(基于ESP-IDFVSCode)】09-Flash存储

2024-04-22 20:45

本文主要是介绍【快速上手ESP32(基于ESP-IDFVSCode)】09-Flash存储,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ESP32中的Flash

关于ESP32中的Flash,我们需要再回顾一下命名规则。

我用的是立创开发板设计的板子,芯片型号是ESP32S3R8N8,因此可以知道我这块板子有8MB的Flash,大家可以参照着命名规则看看自己有多大的Flash容量。

操作Flash

#include "nvs_flash.h"

我们可以使用NVS(非易失性存储)库来对Flash进行操作,以键值对的形式存储数据,使用NVS的话,我们可以把Flash当成是一个巨大的map(C++)或是dict(Python),因此我们需要保存的每一个数据都需要一个键,并且键名不能重复。

初始化&取消初始化

首先我们需要初始化。

esp_err_t nvs_flash_init(void)

不需要参数,直接执行这个函数即可。

当我们使用完NVS的时候,我们再取消初始化。

esp_err_t nvs_flash_deinit(void)

一样是不需要参数。

启用一片空间&释放

esp_err_t nvs_open(const char *namespace_name, nvs_open_mode_t open_mode, nvs_handle_t *out_handle)

参数一传入一个字符串表示是命名空间,这边的命名空间就是我们把Flash再分为多个空间,在不同的命名空间中可以使用相同的键名,比如说名字是space1的空间中可以有叫key的键名,而在叫space2的空间中同样可以有叫key的键名。我们之前说的不能用相同的键名是指在同一个命名空间中不能用相同的键名。命名空间也是为了减少我们键名冲突的概率。

参数二选择打开的模式,NVS_READWRITENVS_READONLY ,分别是读写和只读,我们就选择读写。

参数三是传出参数,把这块命名空间的句柄给我们传出来。

可以理解成我们打开一个文件,命名空间的名字就相当于文件名,既然我们打开了文件,那么也需要关闭文件。

void nvs_close(nvs_handle_t handle)

写入数据

上面完成之后我们就可以通过句柄来进行操作了。

首先先是写入数据。

可以写入的整数型可以有以下几种类型,i8就是int8的意思,就是有符号的8bit数据,u8就是无符号的8bit数据。下面一堆函数的作用以此类推。

esp_err_t nvs_set_i8(nvs_handle_t handle, const char *key, int8_t value);esp_err_t nvs_set_u8(nvs_handle_t handle, const char *key, uint8_t value);esp_err_t nvs_set_i16(nvs_handle_t handle, const char *key, int16_t value);esp_err_t nvs_set_u16(nvs_handle_t handle, const char *key, uint16_t value);esp_err_t nvs_set_i32(nvs_handle_t handle, const char *key, int32_t value);esp_err_t nvs_set_u32(nvs_handle_t handle, const char *key, uint32_t value);esp_err_t nvs_set_i64(nvs_handle_t handle, const char *key, int64_t value);esp_err_t nvs_set_u64(nvs_handle_t handle, const char *key, uint64_t value);

参数一就是句柄,参数二是键值,参数三是写入的值。

除了整数型,还可以写入字符串。

esp_err_t nvs_set_str(nvs_handle_t handle, const char *key, const char *value)

用法也是一样的,只是把整数值换成了字符串,写入的就是字符串了。

除了字符串还可以写入二进制值。

esp_err_t nvs_set_blob(nvs_handle_t handle, const char *key, const void *value, size_t length)

用法也是大差不差,不过最后要提供写入数据的长度。用这个函数可以写入自定义类型。

提交写入申请

esp_err_t nvs_commit(nvs_handle_t handle)

在我们写入数据之后并不保证我们真的就是写进Flash里面了(不过大部分情况是会在正常的时间内真正写入),我们需要提交,也就是使用了上面的函数之后,之前写的数据就会立刻真正的写入Flash,这是为了防止我们的程序突发意外,还没等到真正写入的时刻程序就跑飞了,因此我们最好就是在执行写操作之后就加上这个提交操作。

读出数据

我们能写什么类型的数据自然就能读出什么类型的数据。

函数的命名方式也可以让我们清晰的知道具体是读出什么类型的数据。

esp_err_t nvs_get_i8(nvs_handle_t handle, const char *key, int8_t *out_value);esp_err_t nvs_get_u8(nvs_handle_t handle, const char *key, uint8_t *out_value);esp_err_t nvs_get_i16(nvs_handle_t handle, const char *key, int16_t *out_value);esp_err_t nvs_get_u16(nvs_handle_t handle, const char *key, uint16_t *out_value);esp_err_t nvs_get_i32(nvs_handle_t handle, const char *key, int32_t *out_value);esp_err_t nvs_get_u32(nvs_handle_t handle, const char *key, uint32_t *out_value);esp_err_t nvs_get_i64(nvs_handle_t handle, const char *key, int64_t *out_value);esp_err_t nvs_get_u64(nvs_handle_t handle, const char *key, uint64_t *out_value);esp_err_t nvs_get_str(nvs_handle_t handle, const char *key, char *out_value, size_t *length);esp_err_t nvs_get_blob(nvs_handle_t handle, const char *key, void *out_value, size_t *length);

参数没什么可说的,就是提供键名然后是一个传出参数。

如果我们提供的键名是错误的,也就是在这个命名空间之内没有对应的键值对,那么返回值为ESP_ERR_NVS_NOT_FOUND

删除键值对

删除键值对有两种,一种是删除指定的键值对。

esp_err_t nvs_erase_key(nvs_handle_t handle, const char *key)

提供句柄和键名。

另一种是全部都删除了,也可以理解为清空当前这个命名空间。

esp_err_t nvs_erase_all(nvs_handle_t handle)

当然,上面的操作同样需要使用上面的提交函数才会是当场生效。

实战记录ESP32启动次数

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"void app_main(void){vTaskDelay(3000/portTICK_PERIOD_MS);                                //烧录的时候会先短暂地运行,为了不影响效果这里加个延时if(nvs_flash_init()==ESP_OK)    printf("nvs init success\r\n");     //初始化NVSnvs_handle_t nh;nvs_open("test",NVS_READWRITE,&nh);                                //打开"test"uint16_t count=0;if(nvs_get_u16(nh,"count",&count)==ESP_ERR_NVS_NOT_FOUND){          //读取count值printf("first count\r\n");}else{printf("count is %d\r\n",count);}nvs_set_u16(nh,"count",++count);                                    //++之后再写入Flash里面nvs_commit(nh);                                                     //提交nvs_close(nh);nvs_flash_deinit();while(1){vTaskDelay(10/portTICK_PERIOD_MS);}
}

当我们第一次运行的时候由于没有写入,因此会打印出first count,并且写入0+1。

当我们按下复位之后可以发现读出的数据确实是每次加一的。

 

这篇关于【快速上手ESP32(基于ESP-IDFVSCode)】09-Flash存储的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926815

相关文章

Python实现快速扫描目标主机的开放端口和服务

《Python实现快速扫描目标主机的开放端口和服务》这篇文章主要为大家详细介绍了如何使用Python编写一个功能强大的端口扫描器脚本,实现快速扫描目标主机的开放端口和服务,感兴趣的小伙伴可以了解下... 目录功能介绍场景应用1. 网络安全审计2. 系统管理维护3. 网络故障排查4. 合规性检查报错处理1.

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

SpringCloud Stream 快速入门实例教程

《SpringCloudStream快速入门实例教程》本文介绍了SpringCloudStream(SCS)组件在分布式系统中的作用,以及如何集成到SpringBoot项目中,通过SCS,可... 目录1.SCS 组件的出现的背景和作用2.SCS 集成srping Boot项目3.Yml 配置4.Sprin

SpringBoot集成iText快速生成PDF教程

《SpringBoot集成iText快速生成PDF教程》本文介绍了如何在SpringBoot项目中集成iText9.4.0生成PDF文档,包括新特性的介绍、环境准备、Service层实现、Contro... 目录SpringBoot集成iText 9.4.0生成PDF一、iText 9新特性与架构变革二、环

MySQL 批量插入的原理和实战方法(快速提升大数据导入效率)

《MySQL批量插入的原理和实战方法(快速提升大数据导入效率)》在日常开发中,我们经常需要将大量数据批量插入到MySQL数据库中,本文将介绍批量插入的原理、实现方法,并结合Python和PyMySQ... 目录一、批量插入的优势二、mysql 表的创建示例三、python 实现批量插入1. 安装 PyMyS

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。

MySQL存储过程实践(in、out、inout)

《MySQL存储过程实践(in、out、inout)》文章介绍了数据库中的存储过程,包括其定义、优缺点、性能调校与撰写,以及创建和调用方法,还详细说明了存储过程的参数类型,包括IN、OUT和INOUT... 目录简述存储过程存储过程的优缺点优点缺点存储过程的创建和调用mysql 存储过程中的关键语法案例存储

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe