很多数据是以文件形式存在的,如图片、音频、日志等,当我们需要操作此类数据时,就必须得有一个文件系统,在ESP32项目中,可以使用FLASH存储的一段区间来构建文件系统,也可以外持SD卡来做为文件系统。
FS类是ESP32库内置的文件系统基类,ESP32内置了多种文件系统实现,包括FFat,SPIFFSFS,SDFS等
Flash存储是有刷写次数寿命的,若使用场景需要频繁写入文件,请合理选择文件系统!
FileSystem类是本开发框架对FS类的简单封装,目地是隔离应用侧代码对FS类的依赖,这样有利于应用侧代码的移植和扩展。
在本开发框架中,类似这样的封装还有很多,有兴趣的同学可以参阅源码了解。
下面用两个例子来说明文件系统的使用
从 https://gitee.com/billyzh/esp32-cpp-lesson 下载本教程的源码到本地硬盘文件夹,如d:\esp32-cpp-lesson
在VSCode中,选择【文件】->【打开文件夹...】选择上一步保存的文件夹打开
本示例使用ESP32内置的FLASH存储区间构建Fat文件系统,并进行文件读写操作。
打开项目后,选择config.h文件,修改第10行为
#define APP_LESSON91_A 1
打开unit9-lesson91a/app_config.h文件,设置应用的相关配置
#define CONFIG_USE_FS 1 //启用文件系统模块
#define CONFIG_USE_DISPLAY 1 //启用显示模块
#define CONFIG_USE_TFT_ESPI 1 //使用TFT_eSPI显示驱动
打开unit9-lesson91a/board_config.h文件,设置硬件的相关配置
#define DISPLAY_WIDTH 320 //屏幕宽度像素
#define DISPLAY_HEIGHT 240 //屏幕高度像素
#define DISPLAY_INVERT_COLOR true //是否反转颜色
在ArduinoIDE中使用库管理器安装TFT_eSPI库
打开TFT_eSPI库文件夹内的User_Setup.h文件,修改以下设置:
1.删除行#define ST7789_DRIVER的//注释符,注释其他的芯片驱动;
2.设置引脚如下
#define TFT_MISO -1
#define TFT_MOSI 13
#define TFT_SCLK 12
#define TFT_CS 33 // 片选
#define TFT_DC 23
#define TFT_BL 5 // LED背光
#define TFT_RST 32
本节对TFT-LCD显示屏的引脚做了修改,原因是在前几节中TFT-LCD用到的引脚要用于其它设备。 引脚的合理分配也是设计的重要环节。
实现FileSystem实例,代码如下(unit9-lesson91a/my_board.cpp):
void MyBoard::InitFileSystem() {
Log::Info( TAG, "Init file system ......" );
if (!FFat.begin()) {
FFat.format();
if (!FFat.begin()) {
Log::Info(TAG, "FFat Mount Failed");
return;
}
}
filesystem_ = new FileSystem(FFat);
filesystem_->setTotalBytes(FFat.totalBytes());
filesystem_->setFreeBytes(FFat.freeBytes());
filesystem_->setType("ffat");
Log::Info(TAG, "init filesystem, type: %s, totalbytes: %ld, freebytes: %ld",
filesystem_->type().c_str(), filesystem_->totalBytes(), filesystem_->freeBytes());
}
程序解读
1.先使用内置FFat文件系统类进行初始化,它会将partitions.csv中ffat标签定义的存储区间构建为一个FFat文件系统。
2.创建FileSystem类实例,并用日志输出相关信息
注意:
1.如果ffat标签定义的存储区间之前是别的存储类型,那么重新格式化将导致数据丢失!
2.如果变更partitions分区文件中的区间值,那么可能会导致数据丢失!
3.如果开发板配置项“Erase All Flash Before Sketch Upload”设置为“true”,则会导致数据丢失!
文件读写代码如下(unit9-lesson91a/my_application.cpp):
void MyApplication::OnInit() {
Display *display = Board::GetInstance().GetDisplay();
display->Rotate(1);
FileSystem *fsys = Board::GetInstance().GetFileSystem();
if (fsys==nullptr) {
Log::Warn(TAG, "FileSystem init failed.");
display->GetWindow()->SetText(1, "FileSystem init failed.");
return;
}
char *path = "/hello.txt";
if (fsys->ExistsFile(path)) {
Log::Info(TAG, "read file.");
File f = fsys->OpenFile(path);
if (f) {
String content = f.readString();
display->GetWindow()->SetText(1, "File read success.");
display->GetWindow()->SetText(2, std::string(content.c_str()));
} else {
Log::Warn(TAG, "File %s read failed.", path);
display->GetWindow()->SetText(1, "File read failed.");
}
} else {
Log::Info(TAG, "create file.");
fsys->WriteFile(path, "Hello world!");
display->GetWindow()->SetText(1, "File create success.");
}
}
程序解读
1.通过Board实例取得FileSystem的实例;
2.若根目录存在hello.txt文件,则读取并显示在TFT-LCD显示屏上;
3.若文件不存在,则创建文件并写入“Hello world!”;
指定一个包含FAT存储的分区选项
编译项目并上传开发板检验

再次运行
使用FLASH存储做为文件系统容量相对较小(10M以内),若需要更大的存储空间,可以使用SD卡,不过SD卡的访问速度比FLASH要慢1~2个数量级。
本例使用的SD卡模块采用SPI协议 
SD存储模块详情
打开项目后,选择config.h文件,修改第10行为
#define APP_LESSON91_B 1
应用配置同前一小节。
打开unit9-lesson91b/board_config.h文件,添加以下SD卡配置
#define SD_MOSI_PIN GPIO_NUM_17
#define SD_MISO_PIN GPIO_NUM_16
#define SD_CLK_PIN GPIO_NUM_15
#define SD_CS_PIN GPIO_NUM_14
实现FileSystem实例,代码如下(unit9-lesson91b/my_board.cpp):
void MyBoard::InitFileSystem() {
Log::Info( TAG, "Init file system ......" );
SPI.begin(SD_CLK_PIN, SD_MISO_PIN, SD_MOSI_PIN, SD_CS_PIN);
if (!SD.begin(SD_CS_PIN)) {
Log::Info(TAG, "SD Mount Failed");
return;
}
filesystem_ = new FileSystem(SD);
filesystem_->setTotalBytes(SD.totalBytes());
filesystem_->setFreeBytes(SD.totalBytes() - SD.usedBytes());
filesystem_->setType("SD");
Log::Info(TAG, "init filesystem, type: %s, totalbytes: %ld, freebytes: %ld",
filesystem_->type().c_str(), filesystem_->totalBytes(), filesystem_->freeBytes());
}
程序解读
1.启动SPI协议
2.使用内置SD文件系统类进行初始化,SD卡可在电脑端进行格式化为FAT格式
2.创建FileSystem类实例,并用日志输出相关信息
文件读写代码如下(unit9-lesson91b/my_application.cpp):
代码同示例1
编译项目并上传开发板检验
欧姆定律是指在同一电路中,通过某段导体的电流跟这段导体两端的电压成正比,跟这段导体的电阻成反比。该定律是由德国物理学家乔治·西蒙·欧姆1826年4月发表的《金属导电定律的测定》论文提出的。
本小节是一个Web服务结合SD卡文件系统的应用示例。
本节主要讲解Wifi热点的Web服务使用,以及使用网页交互来控制LED。
本节主要讲解WifiBoard类的功能和HTTPClient库及cJSON的使用。
本节主要讲解TFT-LCD显示屏的使用和Window派生类与TFT_eSPI库的使用。
这篇文章展示了如何将化学与工程、信息技术、现代制造技术紧密结合,以“血氧指标控制的简易供氧器”为载体,组织一次真实的跨学科项目。设计中突出“从需求出发”“闭环控制”“可视化反馈”,不仅呼应了新课标中“跨学科实践”的要求,更贴近生活实际需求,尤其适用于对科技应用、健康关怀有兴趣的学生群体,可作为项目式学习或社团活动的优质课例。
本节主要讲解OLED显示屏的使用和Display类及派生类的介绍及使用。
本节主要讲解用TM1650来驱动四位7段式数码管模块的显示使用。
本节主要讲解FreeRTOS任务间如何使用互斥对象来实现资源互斥访问。
在ESP32的开发,经常会有系统崩溃一直重启的情况,那么如何快速定位出现异常的代码呢?
本节主要讲解FreeRTOS任务间如何使用消息队列、事件组和二进制信号量进行通信。