一起玩儿物联网人工智能小车(ESP32)——62 非易失性存储(NVS)的使用

摘要:本文介绍非易失性存储的使用方法

ESP32芯片提供了丰富的内部存储空间,根据芯片的型号不同,包含的种类和数量也不同。通常情况下可以大致分成这几类:ROM、RAM、SPRAM、RTC内存和FLASH。因此可以几乎在不使用外部存储器的情况下,实现各种各样的应用,十分方便。今天先做一个大致的了解,然后对非易失性存储做个详细的介绍。

ROM(Read-Only Memory):这部分存储器用于程序启动和内核功能调用。大部分ESP32的ROM尺寸为448KB,也有个别型号的ROM要少于448KB。

RAM通常包含片上SRAM和片外PSRAM。片上SRAM(Synchronous RAM)是临时存储数据和指令的区域,对于运行应用程序和处理数据非常有帮助。ESP32的片上SRAM容量为520KB,其中包含了192KB的IRAM和328KB的DRAM。IRAM用来存储关键代码,之前介绍的中断处理程序就是存储在IRAM中,另外一些对时序性要求很高的程序,也可以通过关键字IRAM_ATTR宏,来将其指定存储到IRAM中。DRAM空间有两个用途,一个是用来存储非常量静态数据和零初始化数据,另一个是在程序运行时会用作堆,也称作内部堆。

片外PSRAM的大小可以根据需要扩展,通常为2~8M,其作用是提供更多的数据存储空间,方便程序的使用。

RTC存储是比较特别的SRAM存储器。RTC存储器在设备深度休眠时不掉电,一般比较多配合设备的深度休眠模式的业务场景使用。ESP32芯片有两种RTC存储:RTC快速存储和RTC慢速存储。RTC快速存储为8KB,可以在Deep-sleep模式下RTC启动时用于数据存储以及被主CPU访问。RTC慢速存储也是为8 KB的SRAM,可以在Deep-sleep模式下被协处理器访问。

ESP32是否内置Flash(即NOR或NAND闪存)取决于具体的型号。有些型号可能不含内部Flash,但它们支持外部Flash和SRAM的扩展。外部Flash最大可以支持16MB的容量。Flash具有掉电不丢失的特性,因此许多业务场景经常会使用到Flash。

ESP32根据不同的用途将Flash划分为多个区域。下图为缺省的8M Flash的分区表内容:

在Arduino IDE中定义了一系列的分区表文件,可以使用工具菜单中的“Partition Scheme:”中进行选择。如下图所示:

nvs就是我们接下来要介绍的非易失性存储分区,这个区域的数据掉电之后不会丢失。通常用来存储一些配置性的运行数据,比如Wi-Fi的SSID、密码以及一些需要永久保存的状态信息等等。

ota是与OTA场景相关的存储区,这个将来做OTA升级的时候,再进一步的解释。

SPIFFS分区是一个官方开发的片上Flash设备的嵌入式文件系统,支持磨损均衡、文件系统一致性检查等功能。开发人员可以使用fopen、fclose等标准C文件接口进行操作。该区域大小视具体业务自行定义。

在上面的分区表中,可以看到nvs分区从0x9000地址处开始,大小为0x5000,也就是20480字节的大小。开发者可以根据自己的需要调整nvs分区的大小。

NVS保存数据的形式为键值对。也就是用键来标记对应的数值。其中键必须是ASCII字符,并且长度不能超过15个字符。为了便于使用以及减少潜在的冲突,厂商设计了命名空间来将键值对进行分组,命名空间的名字也是ASCII字符,且长度不超过15个字符。命名空间的名字不能重复。而键值对中键的名字只要在自己的命名空间内不充分就可以了,每个键值对隶属于某一个命名空间且只属于这一个命名空间。

键值对中的值可以为以下几种类型:

  1. 整数型:uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、uint64_t和int64_t
  2. 以\0结尾的字符串
  3. 可变长度的二进制数据(BLOB)

字符串值当前上限为4000字节,其中包括空终止符。BLOB值上限为508,000字节或分区大小的97.6%减去4000字节,以较低值为准。不过,NVS最适合存储一些较小的数据,不建议在NVS中存储较大的数据,如果存储较大的数据,建议使用文件系统。

为现有的键写入新的值可能产生如下结果:

  1. 如果新旧值数据类型相同,则更新值;
  2. 如果新旧值数据类型不同,则返回错误。

读取值时也会执行数据类型检查。如果读取操作的数据类型与该值的数据类型不匹配,则返回错误。

在不加密的情况下,NVS的数据可以通过芯片厂家提供的工具来进行修改,这更适用于在生产阶段的批量初始化。也可以在程序中访问和修改存储的数据。在Arduino中,可以使用Preferences对象来使用NVS存储空间,使用的基本步骤如下:

  1. 引入头文件<Preferences.h>
  2. 创建对象Preferences对象的实例
  3. Preferences对象初始化,初始化参数为命名空间的名字
  4. 调用putXXX()和getXXX()方法来存取NVS中的键值对
  5. isKey()可以用来判断键是否存在,remove()可以用来删除键值对,clear()用来清空键值对

下面来看一个简单的例子。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起玩儿科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值