【快速上手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

相关文章

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

使用SpringBoot+InfluxDB实现高效数据存储与查询

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目... 目录1、项目介绍2、 InfluxDB 介绍3、Spring Boot 配置 InfluxDB4、I

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Mybatis-Plus 3.5.12 分页拦截器消失的问题及快速解决方法

《Mybatis-Plus3.5.12分页拦截器消失的问题及快速解决方法》作为Java开发者,我们都爱用Mybatis-Plus简化CRUD操作,尤其是它的分页功能,几行代码就能搞定复杂的分页查询... 目录一、问题场景:分页拦截器突然 “失踪”二、问题根源:依赖拆分惹的祸三、解决办法:添加扩展依赖四、分页

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

SpringBoot3.X 整合 MinIO 存储原生方案

《SpringBoot3.X整合MinIO存储原生方案》本文详细介绍了SpringBoot3.X整合MinIO的原生方案,从环境搭建到核心功能实现,涵盖了文件上传、下载、删除等常用操作,并补充了... 目录SpringBoot3.X整合MinIO存储原生方案:从环境搭建到实战开发一、前言:为什么选择MinI

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示