Arduino ESP8266 SPI-FFS存储区域
首先请原谅我分开来写,文章老是不过审核。
前言
在前面博文关于ESP8266WiFiWebServer的例程中,大家可以发现,博主基本上都是手动拼装html内容返回,html的内容被固定写在我们的Arduino ESP代码中。
那么这样就有两点弊端:
- ESP8266代码相当臃肿
为了开发方便,web server网页除了自身的html内容之外,还包括一些css文件,甚至引入了JQuery库以及一些图片相关资源。如果把这些内容也直接写入到ESP8266代码中,会导致8266整体代码变大,甚至可能超过flash规定的大小; - 业务职责分离不明确
一般来说,在一个开发团队中,有人负责开发ESP8266业务需求,有人负责开发WebServer网页内容,有人负责硬件部分。直接把html的内容直接写入到ESP8266代码中,就会导致业务职责混乱,并且如果要修改html内容的时候还得一个个改掉arduino的文件,也有可能改错标识符之类的。理想情况应该是,只需要更新web server的html文件就好,原来的esp8266 arduino逻辑不用更新;
基于以上两点弊端,正式引入本篇章需要研究的ESP8266 文件系统(SPI Flash FileSystem,简称为SPIFFS)。
先来看一个概念图:
文件系统可以帮助我们存储一些变更频率不频繁的文件例如网页、配置或者是某些固化的数据等。
其实,我们用得更多的是存储网页,将网页和相关资源(如:图片、html、css、javaScript)存入到flash的SPIFFS区域。
原理如下图:
2. FLASH存储分配
在讲解SPIFFS之前,我们来看看在Arduino环境下ESP8266的flash存储分配,请看下图:
具体可以分为几部分:
1.代码区
又叫做程序存储区,其中又区分为当前代码区(current Sketch),更新代码区(OTA update);
文件系统
这个就是我们这节重点讲解的SPI Flash File System,简称SPIFFS闪存文件系统。
即使文件系统与程序存储在同一个闪存芯片上,烧入新的代码也不会修改文件系统内容。这允许使用文件系统来存储Web服务器的代码数据、配置文件或内容。而这个SPIFFS文件系统的大小可以通过烧写环境来配置,目前一般有1M,2M,3M等等。博主建议如果是NodeMcu板子,可以配置成3M;
为了使用文件系统,需要把下面的头文件包含在代码中:
#include <FS.h>
1.EEPROM
具体讲解请回顾 ESP8266开发之旅 基础篇④ ESP8266与EEPROM
WiFi Config
这个区域就是我们设置WiFi模块配置的时候存储的数据。
3. SPIFFS文件系统
3.1 文件系统限制
ESP8266的文件系统实现必须满足芯片的限制,其中最重要是有限的RAM。SPIFFS之所以被ESP8266选择作为文件系统,是因为它是为小型系统专门设计的,同时是以一些简化和限制为代价的。
首先,SPIFFS不支持目录,它只存储一个“扁平化”的文件列表。但是与传统的文件系统相反,斜杠字符“/”在文件名中是允许的,因此处理目录列表的函数(例如,openDir(“/website”))基本上只是过滤文件名,并保留以前缀(/website/)开始的那些文件。
然后,对于文件名,总共有32个字符限制。一个“\0”字符被保留用于c字符串终止符,因此留给我们31个可用字符长度。
综合起来,这意味着建议保持短文件名,不要使用深嵌套的目录,因为每个文件的完整路径(包括目录、“/”字符、基本名称、点和扩展名)最多只能是31个字符长度。例如,/website/images/bird_thumbnail.jpg 达到了34个字符长度,如果使用它,将导致一些问题。
警告:这个限制很容易达到,如果忽略,问题可能会被忽略,因为在编译和运行时不会出现错误信息。
3.2 文件系统文件添加方式
使用文件系统目的就是为了存储文件,那么存储文件的方式其实可以分为3种:
直接代码中调用FS提供的API在SPIFFS上创建文件;
通过 ESP8266FS 工具把文件上传到SPIFFS;
通过OTA Update的方式上传到SPIFFS;
本质上,无论是通过ESP8266FS或者OTA Update的方式把文件上传到SPIFFS,其底层都是通过调用FS提供的API去完成,所以我们只需要了解FS常用API即可。
4. SPIFFS库
了解一下SPIFFS文件系统常用的操作方法,以下是博主总结的百度脑图:
方法分为3大类:
- SPIFFS专用方法
- Dir对象专用方法
- File对象专用方法
4.1 SPIFFS专用方法
4.1.1 begin —— 挂载SPIFFS文件系统
函数说明
/**
* 挂载SPIFFS文件系统
* @return bool 如果文件系统挂载成功,返回true,否则返回false
*/
bool begin();
注意点:
它必须在其他任何FS API被调用之前先调用;
Arduino IDE配置时需要启用SPIFFS;
4.1.2 format —— 格式化文件系统
函数说明:
/**
* 格式化文件系统
* @return bool 如果格式化成功则返回true
*/
bool format();
注意点:
可以在执行begin()之前或者之后调用
4.1.3 open —— 打开文件
函数说明:
/**
* 打开文件,某种模式下会创建文件
* @param path 文件路径
* @param mode 存取模式
* @return File 返回一个File对象
*/
File open(const char* path, const char* mode);
File open(const String& path, const char* mode);
注意点:
- 路径必须是以斜线开头的绝对路径(如:/dir/filename.txt);
- 模式参数是个用字符串指定的存取模式,其值为“r”、“w”、“a”、“r+”、“w+”和“a+”之中的一个。
r 以只读方式操作文件,读位置在文件的开始位置,文件不存在返回空对象;
r+ 以可读可写方式打开文件,读写位置在文件的开始位置,文件不存在返回空对象;
w 截取文件长度到0或者创建新文件,只能写操作,写位置在文件的开始位置;
w+ 截取文件长度到0或者创建新文件,可读可写操作,写位置在文件的开始位置;
a 在文件末尾追加内容或者文件不存在就创建新文件,追加位置在当前文件的末尾,只能写操作;
a+ 在文件末尾追加内容或者文件不存在就创建新文件,追加位置在当前文件的末尾,可读写操作;
- 如果要检查文件是否打开成功,请使用以下代码:
File f = SPIFFS.open("/f.txt", "w");
if (!f) {
Serial.println("file open failed");
}
4.1.4 exists —— 路径是否存在
函数说明:
/**
* 路径是否存在
* @param path 文件路径
* @return bool 如果指定的路径存在,则返回true,否则返回false
*/
bool exists(const char* path);
bool exists(const String& path);
4.1.5 openDir
—— 打开绝对路径文件夹
函数说明:
/**
* 打开绝对路径文件夹
* @param path 文件路径
* @return Dir 打开绝对路径文件夹,返回一个Dir对象
*/
Dir openDir(const char* path);
Dir openDir(const String& path);
4.1.6 remove
—— 删除绝对路径的文件
函数说明:
/**
* 删除绝对路径的文件
* @param path 文件路径
* @return bool 如果删除成功则返回true,否则返回false
*/
bool remove(const char* path);
bool remove(const String& path);
天下之事常成于困约, 而败于奢靡。 —— 陆 游 |
---|