天天看點

SPIFFS的使用

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
1M 64k, 128k, 256k, 512k
2M
4M 3M
Adafruit HUZZAH 1M, 3M
NodeMCU 0.9
NodeMCU 1.0
Olimex MOD-WIFI-ESP8266(-DEV)
SparkFun Thing
SweetPea ESP-210
WeMos D1 & D1 mini
注:在使用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()

傳回真時就表示目錄枚舉完成。它的調用必須早于

fileName

openFile

函數。

檔案對象

SPIFFS.open

dir.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 參考