【快速上手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");     //初始化NVS

    nvs_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。

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/564611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

洗地机哪个牌子质量最好?这四款公认值得买,总有一款适合你

如今&#xff0c;洗地机在我们家庭清洁中&#xff0c;已经很常见了&#xff0c;它可以让我们快速的完成地面清洁的工作&#xff0c;无需我们手动去清洗滚布&#xff0c;大大的节省了我们清洁时间&#xff0c;给我们腾出来了更多时间去享受生活。但是目前&#xff0c;可供选择的…

通过WHM面板重启服务器

看到一位用户反馈他购买了Hostease的独立服务器带cPanel面板的&#xff0c;但是该用户想要重启服务器&#xff0c;通过cPanel面板进行操做管理重启&#xff0c;但是没有找到具体位置&#xff0c;因此留言寻求帮助&#xff0c;具体的操做步骤如下&#xff1a; 1.登录到WHM面板 2…

Oracle中的 plsql语法

01-plsql 为什么要plsql 复杂的业务逻辑 可以使用 编程语言实现 sql无法实现 plsql也可以实现复杂的业务逻辑 为不直接使用编程语言 而是学习plsql plsql会比直接使用 编程语言 速度更快 基本语法&#xff1a; [declare --声明变量 变量名 变量类型 ] begin --代码逻辑 …

ai扩写软件有哪些免费的?分享4款扩写好用的!

随着人工智能技术的飞速发展&#xff0c;AI扩写软件逐渐成为了内容创作者们的得力助手。它们能够迅速将简短的文案扩写成内容丰富、结构完整的文章&#xff0c;大大提高了创作效率。本文将为您盘点几款免费的AI扩写软件&#xff0c;助您在今日头条、百家号等自媒体平台上轻松打…

【快速上手ESP32(基于ESP-IDFVSCode)】08-SPI

SPI SPI&#xff0c;全称Serial Peripheral Interface&#xff0c;即串行外设接口&#xff0c;是一种同步串行接口技术。它最初由Motorola公司推出&#xff0c;并在其MC68HCXX系列处理器上首次定义。SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器&#xff0c;以及数字信…

【HCIP学习】重发布和路由策略

一、重发布&#xff08;路由引入&#xff09; 1、背景&#xff1a; 一个网络拓扑中存在多种不同的路由协议&#xff0c;为了使多种不同的路由协议间能相互通信&#xff0c;出现了路由引入 为啥会存在多种不同的网络&#xff1f; 例如&#xff1a;OSPF由于区域架构的限制&am…

《苍穹外卖》Day02部分知识点记录

一、属性的拷贝以及密码的加密 使用org.springframework.beans中的BeanUtils.copyProperties()方法时&#xff0c;二者的属性名必须要一致。 /*** 新增员工* param employeeDTO*/Overridepublic void save(EmployeeDTO employeeDTO) {Employee employee new Employee();// 对…

renren-fast-vue-master常见报错和解决

前言&#xff1a; 因为最近博主的实习&#xff0c;所以在小破站写那个分布式微服务电商的项目&#xff0c;什么什么商城就不说了&#xff0c;大家都明白&#xff0c;相信大家像我一样&#xff0c;在使用renren-fast-vue-master的时候都很是头痛&#xff0c;项目还没开始就结束了…

防、治、管融合一体化旅居健康守护系统

随着人口老龄化趋势的加剧和人们生活水平的提高&#xff0c;养老服务需求不断增长。旅居养老作为一种新型的养老模式&#xff0c;逐渐受到广大老年人的青睐。在生命健康服务运营平台中&#xff0c;为了给老人提供全方位、个性化的生命健康服务&#xff0c;我们平台也特意开设了…

PUBG问题解决:吃鸡请重新安装软件MSVCP140.dll

近年来&#xff0c;随着电子竞技游戏的兴起&#xff0c;《绝地求生》&#xff08;俗称“吃鸡”&#xff09;成为了全球范围内备受瞩目的游戏之一。然而&#xff0c;由于游戏本身对计算机硬件和软件的要求较高&#xff0c;许多玩家在游戏过程中可能会遇到各种问题。其中之一就是…

【Yolov系列】Yolov5学习(一)补充2:Focus模块详解

一、相关知识 Focus模块是一种用于特征提取的卷积神经网络层&#xff0c;用于将输入特征图中的信息进行压缩和组合&#xff0c;从而提取出更高层次的特征表示&#xff0c;它被用作网络中的第一个卷积层&#xff0c;用于对输入特征图进行下采样&#xff0c;以减少计算量和参数量…

IS62C256AL-45TLI功能参数介绍及如何优化性能

IS62C256AL-45TLI功能和参数介绍及如何优化性能-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 产品品种:静态随机存取存储器 RoHS:是 存储容量:256 kbit 组织:32 k x 8 访问时刻:45 ns 接口类型:Parallel 电源电压-最大:5.5 V 电源电压-最小:4.5 V 电源电流—最大值:25 mA 最小…

如何高效协作?

前言 上一篇文章我们分享了《如何高效沟通》&#xff0c;本篇文章继续延伸至更复杂的场景&#xff0c;跨团队/跨部门协作。 什么是协同&#xff1f; 协同也会被称为协作合作&#xff0c;无论是哪种类型的团队&#xff0c;无论哪种方式的工作场景&#xff0c;都一定会有协作发…

力扣110. 平衡二叉树

思路&#xff1a;与二叉树最大高度类似&#xff0c;但是这里需要返回 -1 的高度来标识不是平衡二叉树&#xff0c;判断左右子树的高度相差大于1则不平衡&#xff0c;否则就是平衡。 class Solution {public boolean isBalanced(TreeNode root) {int ans func(root);if(ans >…

MySQL主从复制实现高可用性和负载均衡

大家好&#xff0c;我是咕噜铁蛋&#xff0c;今天我想和大家聊聊MySQL主从复制如何帮助我们实现高可用性和负载均衡。在如今的大数据时代&#xff0c;数据库的稳定性和性能成为了企业关注的重点&#xff0c;而MySQL主从复制正是解决这两个问题的重要工具。 一、MySQL主从复制简…

Linux进程和任务管理

目录 一.程序和进程的关系 程序 进程 线程 线程与进程的区别 二.查看进程信息ps 方法一 常用选项 方法二 三.TOP动态查看进程信息 进程信息区各列解释 top常用命令 系统查看命令总结 查看进程信息pgrep 查看进程树pstree 四.控制进程 进程的启动方式 进程的前…

[C语言实现]码林盟主秘籍——《手撕八大排序》

​ ​ &#x1f970;作者: FlashRider &#x1f30f;专栏: 初阶数据结构 &#x1f356;知识概要&#xff1a;详解八大排序的原理、时间复杂度分析、以及代码实现。 目录 八大排序 插入排序 直接插入排序 希尔插入排序 选择排序 冒泡排序 计数排序 堆排序 快速排序 霍…

Gather:基于 DePIN 体系构建的 Web3 社交生态

“Gather 通过搭建一套基于 DePIN 的 Web3 社交体系&#xff0c;正在成为 SocialFi 革命的早期推动者。” 基于互联网的社交&#xff0c;正在为人们提供了远距离沟通和连接的便利&#xff0c;打破了地理障碍&#xff0c;这种具备包容性、广泛性的线上连接&#xff0c;加速了信息…

Git禁止松散对象loose objects弹窗

打开仓库时&#xff0c;弹窗如图 This repository currently has approximately XXXX loose objects.解决办法&#xff1a;见How to skip “Loose Object” popup when running ‘git gui’ Git v1.7.9 或以上版本&#xff0c;执行git config --global gui.gcwarning false

什么是XXE攻击?如何进行防护

安全性很难做到正确&#xff0c;即使在当今具有安全意识的世界中&#xff0c;也存在一些严重的漏洞&#xff0c;例如 XML 外部实体 (XXE)&#xff0c;它们被忽视并最终成为破坏的原因。 XML 外部实体 (XXE) 攻击是一种计算机安全漏洞&#xff0c;通常存在于 Web 应用程序中&…