SPIFFS的使用

简介: SPIFFS我个人很喜欢ESP8266这个板,主要是由于它提供了一系列价格低廉、高可用的IoT开发及接入方案。你是否知道在ESP8266的系统闪存可以用来存储代码甚至是文件吗?这个文件系统可以让我们存储一些变更频率不频繁的文件例如网页、配置或者是某些固化的数据等。
SPIFFS

我个人很喜欢ESP8266这个板,主要是由于它提供了一系列价格低廉、高可用的IoT开发及接入方案。你是否知道在ESP8266的系统闪存可以用来存储代码甚至是文件吗?

这个文件系统可以让我们存储一些变更频率不频繁的文件例如网页、配置或者是某些固化的数据等。芯片内置这样的小型文件系统后ESP8266就相当于是一块Arduino+WIFI+SD扩展板的功能了,但价格上却只需要比Arduino低上很多。正因为了它我们就能在里面植入一些其它的固件用于支持像Lua或者Micropython这样的脚本类语言引擎以简化嵌入式设备的编程。

它就是SPIFFs - SPI Flash Filing System!

环境配置

那怎么来使用SPIFFs呢?首先你需要在Arduino中加入对ESP8266这个板子的支持,在我以前的文章Arduino Core For ESP8266中对此已经有所介绍。其次,你需要下载一个Arduino IDE的插件Arduino-ESP8266FS-Plugin,解压缩至<home>/Arduino/tools/然后重启Arduino后就会看到ESP8266 Sketch Data Upload 的菜单。

ESP8266由于有很多种不同的板子,所以在使用SPIFFS之前应该先确认你所用的板子的SPIFFS的大小。

目录
Arduino IDE 插件

Flash的结构:

以下是ESP8266的Flash基本结构:

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
      Sketch    OTA更新   文件系统   EEPROM  WiFi config (SDK)

文件系统的大小依赖于Flash芯片的大小,下表为现时收集到的常见芯片的FLash大小:

主板 Flash(bytes) 文件系统(bytes)
Generic module 512k 64k
Generic module 1M 64k, 128k, 256k, 512k
Generic module 2M 1M
Generic module 4M 3M
Adafruit HUZZAH 4M 1M, 3M
NodeMCU 0.9 4M 1M, 3M
NodeMCU 1.0 4M 1M, 3M
Olimex MOD-WIFI-ESP8266(-DEV) 2M 1M
SparkFun Thing 512k 64k
SweetPea ESP-210 4M 1M, 3M
WeMos D1 & D1 mini 4M 1M, 3M

注:在使用SPIFFS功能之前需要在文件内引用头文件:
#include "FS.h"

使用SPIFFS

ESP8266FS插件其实只是在当前项目目录下创建了一个data目录,我们只要将需要上传到芯片文件系统的内容放置在这个 data目录中就可以了,然后点击ESP8266 Skech Data Upload Arduino IDE就会将这个目录的文件写入到SPIFFS中了。要注意的是文件的大小不能超过板子SPIFFS的大小,否则会上传失败。

我们就尝试将一个index.html网页文件放到data目录,然后将其上传到ESP8266中,接下来用以下的代码将SPIFFS中的index.html读出来:


#include"FS.h"

void setup() {
  Serial.begin(115200);

  bool ok = SPIFFS.begin();
  if (ok) {
    Serial.println("ok");
    //检查文件是否存在
    bool exist = SPIFFS.exists("/index.html");

    if (exist) {
      Serial.println("The file exists!"); 

      File f = SPIFFS.open("/index.html", "r");
      if (!f) {
        // 在打开过程中出现问题f就会为空
        Serial.println("Some thing went wrong trying to open the file...");
      }
      else {
        int s = f.size();
        Serial.printf("Size=%d\r\n", s);

        //读取index.html的文本内容
        String data = f.readString();
        Serial.println(data);

        //关闭文件
        f.close();
      }
    }
    else {
      Serial.println("No such file found.");
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}

FS的参考

SPIFFS对象

begin

SPIFFS.begin()

该方法用于挂载SPIFFS文件系统,必须在使用SPIFFS之前就调用,一般都会在setup()过程调用。该方法如果调用成功将会返回true,否则返回false

format

SPIFFS.format()

格式化文件系统。返回true表示格式化成功。

open

SPIFFS.open(path, mode)

打开指定位置上的一个文件并返回File对象。

  • path - 文件的路径(如:/test.text)
  • mode - 文件的读写模式,可以为 "r", "w", "a", "r+", "w+", "a+"中的任意一个,这个与C言语中访问文件系统的方式是一样的。

该方法返用成功后会返回一个File对象,否则就会返回空。

File f = SPIFFS.open("/f.txt", "w");
if (!f) {
    Serial.println("file open failed");
}

exists

SPIFFS.exists(path)

检测指定文件或目录是否存在。

openDir

SPIFFS.openDir(path)

打开指定目录并返回一个目录对象实例。

remove

SPIFFS.remove(path)

删除指定绝对路径上的文件或目录。

rename

SPIFFS.rename(pathFrom, pathTo)

重命名。

info

FSInfo fs_info;
SPIFFS.info(fs_info);

获取一个文件系统信息结构。

文件系统信息结构

struct FSInfo {
    size_t totalBytes;   // 可用量
    size_t usedBytes;  // 已用
    size_t blockSize;   // 块大小
    size_t pageSize;  // 页大小
    size_t maxOpenFiles; // 最大打开文件数
    size_t maxPathLength; // 最大文件路径长度
};

目录 (Dir)

目录对象常用于枚举,它会提供三个方法:next(),fileName(), 和 openFile(mode)

以下例子用于枚举指定目录下的子目录、文件名和文件大小:

Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
    Serial.print(dir.fileName());
    File f = dir.openFile("r");
    Serial.println(f.size());
}

dir.next()返回真时就表示目录枚举完成。它的调用必须早于fileNameopenFile函数。

文件对象

SPIFFS.opendir.openFile 函数都可以返回一个File文件对象实例。这个对象用于处理所有的文件流,例如:readBytes, findUntil, parseInt, println

seek

file.seek(offset, mode)

移动文件指针。

position

file.position()

返回当前文件指针的位置 。

size

file.size()

返回文件的大小。

name

String name = file.name();

返回文件名。

close

file.close()

关闭并释放文件对象。

在实际的运用场景中,合理地使用SPIFFS会给我们省下很多的时间甚至是生产成本,希望这篇短文能给你在使用ESP8266的过程中给予一些帮助。

ESP8266 Core 参考

相关文章
|
7月前
|
Shell
在Bash中检查变量是否为空的几种方法
在Bash中检查变量是否为空的几种方法
537 0
在Bash中检查变量是否为空的几种方法
|
监控 NoSQL
JLink + GDB 调试方法
本节主要介绍嵌入式开发中常用的JLink+GDB调试方法。 调试所需软件 J-link,可以从https://www.segger.com下载对应操作系统的软件包,然后安装(注意:segger是仿真器的名字,相当常用的一款,仿真器的接口也是固定的,一般开发版上都会带有这个调试接口,如图) 运行JLinkGDBServer 按照上图中的配置,配置GDBServer,然后点击OK,进入下一个界面 注意,如果硬件连接没有问题,那么上图中的J-Link和 Device栏中显示绿色,GDB显示为红色,因为我们还没有运行GDB软件。
6756 46
|
存储 缓存 关系型数据库
STM32内部flash详解(1)(上)
STM32内部flash详解(1)
|
数据采集 机器学习/深度学习 自然语言处理
文本处理技能与文本数据清洗、提取、分词与统计
文本处理技能与文本数据清洗、提取、分词与统计
|
存储 算法 编译器
利用C语言读取BMP文件
BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。在系统中以BMP为扩展名保存。   打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图.   一般的bmp图像都是24位,也就是真彩。每8位为一字节,24位也就是使用三字节来存储每一个像素的信息,三个字节对应存放r,g,b三原色的数据每个字节的存贮范围都
277 0
利用C语言读取BMP文件
|
NoSQL Redis C++
cpp_redis (Windows C++ Redis客户端静态库,C++11实现)源码编译及使用
cpp_redis (Windows C++ Redis客户端静态库,C++11实现)源码编译及使用
1032 0
|
API 调度 芯片
FreeRTOS记录(三、RTOS任务调度原理解析_Systick、PendSV、SVC)
RTOS的任务调度原理和所使用的内核中断、寄存器息息相关 文中截图大多是《Cortex-M3与Cortex-M4权威指南》翻译版本里面的内容 需要对内核有一定的了解,本文尽量用简单的描述表达清楚 虽然是FreeRTOS的记录,但是原理上来说对于其他RTOS也是一样的!
1013 0
FreeRTOS记录(三、RTOS任务调度原理解析_Systick、PendSV、SVC)
运行JProfiler:ERROR: Invalid license key. Aborting
运行JProfiler:ERROR: Invalid license key. Aborting
1449 0
运行JProfiler:ERROR: Invalid license key. Aborting
|
UED
Qt之QSS(动态属性)
简述 QSS可以定制应用程序的外观,无需关注Qt样式背后的魔力。从非常轻微到极其复杂的调整,样式表都可以做到。对于一个完全定制和独特的用户体验,QtQuick和QGraphicsView是更好的选择。 简述 自定义属性 限制 示例 效果 源码 QSS 更多参考 自定义属性 为了用户界面外观的动态变化,属性选择器可以与动态属性组合使用。动态属性
2820 0