Arduino ESP32 flash数据存储结构

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino ESP32 flash数据存储结构相关的知识,希望对你有一定的参考价值。

Arduino ESP32 flash数据存储结构


想了解ESP32 flash数据存储结构需要从分区表开始了解。一点类似一台电脑上挂载的硬盘一样。

  • 分区表保存 SPI flash 各区信息,包括引导程序、各种应用程序二进制文件、数据及文件系统等
/*在Arduino环境中使用的flash布局
|----|-------|--------|-------|----------|
^    ^       ^        ^       ^        
NVS otadata app0    app1 SPIFFS/FATFS  

硬件信息配置文件位置:

这是我的电脑,文件位置:C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\1.0.6\\tools\\partitions

  • 里面存放着不同分区表配置文件。就如同电脑分区,根据不同的需求,自定义分区大小一样。

常规的数据分区结构:

非易失性存储库(NVS)

非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。是esp-idf 存储配置信息的主要方法。

  1. 底层存储.
    NVS 通过调用 spi_flash_read|write|erase API 对主 flash 的部分空间进行读、写、擦除操作,包括 data 类型和 nvs 子类型的所有分区。应用程序可调用 nvs_open API 选择使用带有 nvs 标签的分区,也可以通过调用 nvs_open_from_part API 选择使用指定名称的任意分区。如果 NVS 分区被截断(例如,更改分区表布局时),则应擦除分区内容。可以使用 ESP-IDF 构建系统中的 idf.py erase_flash 命令擦除 flash 上的所有内容。
    NVS 最适合存储一些较小的数据,而非字符串或二进制大对象 (BLOB) 等较大的数据。如需存储较大的 BLOB 或2者字符串,请考虑使用基于磨损均衡库的 FAT 文件系统。
  2. 键值对的形式存储数据。

NVS 的操作对象为键值对,其中键是 ASCII 字符串,当前支持最大键长为 15 个字符,值可以为以下几种类型:

typedef enum 
    PT_I8, PT_U8, PT_I16, PT_U16, PT_I32, PT_U32, PT_I64, PT_U64, PT_STR, PT_BLOB, PT_INVALID
 PreferenceType;
  • 整数型:uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、uint64_t 和 int64_t
 size_t putChar(const char* key, int8_t value);
        size_t putUChar(const char* key, uint8_t value);
        size_t putShort(const char* key, int16_t value);
        size_t putUShort(const char* key, uint16_t value);
        size_t putInt(const char* key, int32_t value);
        size_t putUInt(const char* key, uint32_t value);
        size_t putLong(const char* key, int32_t value);
        size_t putULong(const char* key, uint32_t value);
        size_t putLong64(const char* key, int64_t value);
        size_t putULong64(const char* key, uint64_t value);
        size_t putFloat(const char* key, float_t value);
        size_t putDouble(const char* key, double_t value);
        size_t putBool(const char* key, bool value);
  • 以 \\0 结尾的字符串
 		size_t putString(const char* key, const char* value);
        size_t putString(const char* key, String value);
        size_t putBytes(const char* key, const void* value, size_t len);

可变长度的二进制数据 (BLOB) 键必须唯一,为现有的键写入新的值可能产生如下结果:如果新旧值数据类型相同,则更新值; 如果新旧值数据类型不同,则返回错误。

  • EEPROM

在EPS32中已经将EEPROM弃用。对于ESP32上的新应用程序,建议使用NVS为首选项。提供EEPROM是为了向后兼容现有的Arduino应用程序。EEPROM是使用NVS中的单个blob实现的,因此它是容器(Flash)中的容器(NVS)。因此,它不会是一种高性能存储方法。首选项将直接使用nvs,并将每个条目存储为其中的单个对象。所以现在的EEPROM也仅是在函数功能上向后兼容,实际储存方式已经完全变了,这需要我们在实际应用中注意。

  • 命名空间(namespace)

为了减少不同组件之间键名的潜在冲突,NVS 将每个键值对分配给一个命名空间。命名空间的命名规则遵循键名的命名规则,即最多可占 15 个字符。命名空间的名称在调用 nvs_open 或 nvs_open_from_part 中指定,调用后将返回一个不透明句柄,用于后续调用 nvs_read_、nvs_write_ 和 nvs_commit 函数。这样,一个句柄关联一个命名空间,键名便不会与其他命名空间中相同键名冲突。请注意,不同 NVS 分区中具有相同名称的命名空间将被视为不同的命名空间。

虚拟文件系统组件

虚拟文件系统 (VFS) 组件可为一些驱动提供一个统一接口。有了该接口,用户可像操作普通文件一样操作虚拟文件。这类驱动程序可以是 FAT、SPIFFS 等真实文件系统,也可以是有文件类接口的设备驱动程序。

VFS 组件支持 C 库函数(如 fopen 和 fprintf 等)与文件系统 (FS) 驱动程序协同工作。在高层级,每个 FS 驱动程序均与某些路径前缀相关联。当一个 C 库函数需要打开文件时,VFS 组件将搜索与该文件所在文件路径相关联的 FS 驱动程序,并将调用传递给该驱动程序。针对该文件的读取、写入等其他操作的调用也将传递给这个驱动程序。

  • 例如,您可以使用 /fat 前缀注册 FAT 文件系统驱动,之后即可调用 fopen("/fat/file.txt", “w”)。之后,VFS 将调用 FAT 驱动的 open 函数,并将参数 /file.txt 和合适的打开模式传递给 open 函数;后续对返回的 FILE* 数据流调用 C 库函数也同样会传递给 FAT 驱动。
  1. FAT 文件系统

使用 FatFs 库来实现 FAT 文件系统。FatFs 库位于 fatfs 组件中,您可以直接使用,也可以借助 C 标准库和 POSIX API 通过 VFS(虚拟文件系统)使用 FatFs 库的大多数功能。
此外,我们对 FatFs 库进行了扩展,新增了支持可插拔磁盘 I/O 调度层,从而允许在运行时将 FatFs 驱动映射到物理磁盘。

  1. SPIFFS 文件系统

SPIFFS 是一个用于 SPI NOR flash 设备的嵌入式文件系统,支持磨损均衡、文件系统一致性检查等功能。

以上是关于Arduino ESP32 flash数据存储结构的主要内容,如果未能解决你的问题,请参考以下文章

Arduino框架下对ESP32 NVS非易失性存储解读以及应用示例

Arduino方式开发ESP32笔记:使用Preferences保存数据

Arduino ESP32 flash各型号分区表配置详略整理

Arduino ESP32 flash分区表配置信息查询示例程序

Arduino IDE增加ESP32flash分区配置选项

如何使用Arduino ESP32将数据存储到MicroSD(软SPI和硬SPI)