一.SPIFFS介绍
SPIFFS(Serial Peripheral Interface Flash File System)是一个为 SPI NOR 闪存设计的嵌入式文件系统,专为资源受限的嵌入式系统优化。它被广泛应用于 ESP32/ESP8266 等 IoT 设备中管理非易失性存储数据
主要应用场景:
1.配置文件存储:保存 Wi-Fi 凭证、设备参数等关键配置信息
2.Web资源驻留:存储网页模板、JavaScript/CSS 文件等 HTTP 服务器资源2
3.日志记录:记录设备运行状态和异常信息(最多支持 4096 个独立日志文件)
4.OTW更新支撑:作为空中固件更新时的临时存储区域
二.esp32-s3里的存储
我们可以看到在ESP32-S3芯片设计里主要的存储部分有两个,一个是flash,另一个是PSRAM。
这两个接口都是通过spi接口来进行访问的。
ESP32-S3的ROM,RAM,FLASH
而spiffs是主要作用在flash里的一个轻量级文件系统。就可以实现和fatfs文件系统类似的功能,可以在flash里读写和创建文件。在esp32-s3里flash里的容量高达16MB,所以这里可以存入一些我们日常使用的字库文件等。
三.分区表
提到flash就不得不提到分区表。ESP32-S3 的 Flash 存储器,它被划分为多个分区,每个分区都有特定的用途。而Flash分区表它定义了 Flash 存储器的布局。Flash 分区表中的每个条目都描述了一个分区的属性,包括其在 Flash 中的位置(偏移量)、大小、类型、以及其他一些属性。
述以官方例程里面的分区表进行描述。
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
ota_0, app, ota_0, 0x110000, 1M,
ota_1, app, ota_1, 0x210000, 1M,
partition_tables
分区:存储描述flash信息里的分区表。nvs
分区:非易失性存储 (NVS) 库,主要用于在 flash 中存储键值格式的数据,也就是可以存入一些想要掉电不丢失的数据otadata
分区:记录启动信息,描述启动具体哪一个OTA分区phy_init
分区:用于存储芯片的PHY有关数据,芯片网络有关数据存放在此分区- factory 分区:工厂程序分区,通过串口烧录在芯片内的第一个出厂程序
ota_0
分区:OTA升级的程序分区ota_1
分区:OTA升级的程序分区
分区表的结构
根据官方文档所说
分区表的长度为0xC00字节,最多可以保存95条分区表条目。分区表数据后还保存着该表的MD5校验和,用于验证分区表的完整性。因此,分区表占据了一个整个的闪存扇区,大小为0x1000(4KB)。结果是,任何在其后的分区必须至少位于(默认偏移量)+0x1000的位置。
分区表中的每个条目都有一个名称(标签)、类型(应用、数据或其他内容)、子类型和加载分区的闪存中的偏移量。
3.1 分区表操作指南
我们可以使用指令idf.py partition-table
查看当前的分区表以及每个区的空间大小
当然我们也可也自己来定义分区表
我们可以自己定义一个csv后缀的文件。
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000, ,
phy_init, data, phy, 0xf000, 0x1000, ,
factory, app, factory, 0x10000, 0x1F0000, ,
vfs, data, fat, 0x200000, 0xA00000, ,
storage, data, spiffs, 0xc00000, 0x400000, ,
我们比较要注意的就是subtype,这个决定了你这个区的作用,例如创建了一个名为storage的分区,subtype为spiffs,这就代表storage这个区被作用为spiffs文件系统,地址为0xc00000,大小是0x400000,也就是4MB。
这里提一下vfs虚拟文件系统
虚拟文件系统 (VFS) 组件为驱动程序提供一个统一接口,可以操作类文件对象。这类驱动程序可以是 FAT、SPIFFS 等真实文件系统,也可以是提供文件类接口的设备驱动程序。
我们发现,每个文件系统的函数可能都不太一样,如果我们有频繁切换文件系统的要求,这样就会非常不方便,因此我们引入虚拟文件系统vfs这个概念。
我们只需要实现vfs规定函数的功能,这样无论是哪个系统,我们只需要调用vfs虚拟文件系统的接口就可以实现了。
所以,vfs区存储的就是实现vfs虚拟文件系统的一些代码。
四.外部文件烧入的spiffs里
每次通过程序代码去保存和修改文件也太麻烦了,那么有没有一种工具,可以直接向开发板中传文件呢?方式是有的,我们只需要每次镜像一份spiffs文件系统,然后填充我们要存放的文件,最后之间烧入到flash里就可以了。
在这里我参考的是点我这篇文章。主要有两种实现方式
4.1spiffsgen.py 工具
SPIFFS 提供了一个 Python 工具 spiffsgen.py,用于从主机文件夹内容生成文件系统镜像。使用方法就两步。
PIFFS 提供了一个 Python 工具 spiffsgen.py,用于从主机文件夹内容生成文件系统镜像。使用方法就两步。
这个方式我没实现成功,故在此不多介绍,可以之间看我给出的链接
4.2spiffs_create_partition_image 命令
spiffs_create_partition_image 同样一个用于将文件系统中的文件打包成 SPIFFS 镜像并烧录到 ESP32 闪存中的命令,可以在程序烧录阶段一同将自定义的SPIFFS 文件镜像烧录到开发板。我们只需要在main/cmakelists.txt配置这个命令就可以在烧入时将我们资源之间烧入到spiffs里
spiffs_create_partition_image(my_spiffs_partition my_folder FLASH_IN_PROJECT)
my_spiffs_partition
:分区名my_folder
:资源路径FLASH_IN_PROJECT
:表示烧入到flash里
这是官方的介绍
例如我们现在有一个storage文件夹的资源
我们只需要在main/cmakelists.txt配置一句4.2spiffs_create_partition_image 就可以在烧录时同步将资源一块烧入到spiffts里
最后的输出结果