SPIFFS的使用

SPIFFS

我個(gè)人很喜歡ESP8266這個(gè)板,主要是由于它提供了一系列價(jià)格低廉、高可用的IoT開發(fā)及接入方案。你是否知道在ESP8266的系統(tǒng)閃存可以用來存儲(chǔ)代碼甚至是文件嗎?

這個(gè)文件系統(tǒng)可以讓我們存儲(chǔ)一些變更頻率不頻繁的文件例如網(wǎng)頁、配置或者是某些固化的數(shù)據(jù)等。芯片內(nèi)置這樣的小型文件系統(tǒng)后ESP8266就相當(dāng)于是一塊Arduino+WIFI+SD擴(kuò)展板的功能了,但價(jià)格上卻只需要比Arduino低上很多。正因?yàn)榱怂覀兙湍茉诶锩嬷踩胍恍┢渌墓碳糜谥С窒馤ua或者M(jìn)icropython這樣的腳本類語言引擎以簡化嵌入式設(shè)備的編程。

它就是SPIFFs - SPI Flash Filing System!

環(huán)境配置

那怎么來使用SPIFFs呢?首先你需要在Arduino中加入對(duì)ESP8266這個(gè)板子的支持,在我以前的文章Arduino Core For ESP8266中對(duì)此已經(jīng)有所介紹。其次,你需要下載一個(gè)Arduino IDE的插件Arduino-ESP8266FS-Plugin,解壓縮至<home>/Arduino/tools/然后重啟Arduino后就會(huì)看到ESP8266 Sketch Data Upload 的菜單。

ESP8266由于有很多種不同的板子,所以在使用SPIFFS之前應(yīng)該先確認(rèn)你所用的板子的SPIFFS的大小。

目錄
Arduino IDE 插件

Flash的結(jié)構(gòu):

以下是ESP8266的Flash基本結(jié)構(gòu):

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
      Sketch    OTA更新   文件系統(tǒng)   EEPROM  WiFi config (SDK)

文件系統(tǒng)的大小依賴于Flash芯片的大小,下表為現(xiàn)時(shí)收集到的常見芯片的FLash大小:

主板 Flash(bytes) 文件系統(tǒng)(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功能之前需要在文件內(nèi)引用頭文件:
#include "FS.h"

使用SPIFFS

ESP8266FS插件其實(shí)只是在當(dāng)前項(xiàng)目目錄下創(chuàng)建了一個(gè)data目錄,我們只要將需要上傳到芯片文件系統(tǒng)的內(nèi)容放置在這個(gè) data目錄中就可以了,然后點(diǎn)擊ESP8266 Skech Data Upload Arduino IDE就會(huì)將這個(gè)目錄的文件寫入到SPIFFS中了。要注意的是文件的大小不能超過板子SPIFFS的大小,否則會(huì)上傳失敗。

我們就嘗試將一個(gè)index.html網(wǎng)頁文件放到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) {
        // 在打開過程中出現(xiàn)問題f就會(huì)為空
        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的文本內(nèi)容
        String data = f.readString();
        Serial.println(data);

        //關(guān)閉文件
        f.close();
      }
    }
    else {
      Serial.println("No such file found.");
    }
  }
}

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

FS的參考

SPIFFS對(duì)象

begin

SPIFFS.begin()

該方法用于掛載SPIFFS文件系統(tǒng),必須在使用SPIFFS之前就調(diào)用,一般都會(huì)在setup()過程調(diào)用。該方法如果調(diào)用成功將會(huì)返回true,否則返回false

format

SPIFFS.format()

格式化文件系統(tǒng)。返回true表示格式化成功。

open

SPIFFS.open(path, mode)

打開指定位置上的一個(gè)文件并返回File對(duì)象。

  • path - 文件的路徑(如:/test.text)
  • mode - 文件的讀寫模式,可以為 "r", "w", "a", "r+", "w+", "a+"中的任意一個(gè),這個(gè)與C言語中訪問文件系統(tǒng)的方式是一樣的。

該方法返用成功后會(huì)返回一個(gè)File對(duì)象,否則就會(huì)返回空。

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

exists

SPIFFS.exists(path)

檢測(cè)指定文件或目錄是否存在。

openDir

SPIFFS.openDir(path)

打開指定目錄并返回一個(gè)目錄對(duì)象實(shí)例。

remove

SPIFFS.remove(path)

刪除指定絕對(duì)路徑上的文件或目錄。

rename

SPIFFS.rename(pathFrom, pathTo)

重命名。

info

FSInfo fs_info;
SPIFFS.info(fs_info);

獲取一個(gè)文件系統(tǒng)信息結(jié)構(gòu)。

文件系統(tǒng)信息結(jié)構(gòu)

struct FSInfo {
    size_t totalBytes;   // 可用量
    size_t usedBytes;  // 已用
    size_t blockSize;   // 塊大小
    size_t pageSize;  // 頁大小
    size_t maxOpenFiles; // 最大打開文件數(shù)
    size_t maxPathLength; // 最大文件路徑長度
};

目錄 (Dir)

目錄對(duì)象常用于枚舉,它會(huì)提供三個(gè)方法:next(),fileName(), 和 openFile(mode)

以下例子用于枚舉指定目錄下的子目錄、文件名和文件大?。?/p>

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

dir.next()返回真時(shí)就表示目錄枚舉完成。它的調(diào)用必須早于fileNameopenFile函數(shù)。

文件對(duì)象

SPIFFS.opendir.openFile 函數(shù)都可以返回一個(gè)File文件對(duì)象實(shí)例。這個(gè)對(duì)象用于處理所有的文件流,例如:readBytes, findUntil, parseInt, println。

seek

file.seek(offset, mode)

移動(dòng)文件指針。

position

file.position()

返回當(dāng)前文件指針的位置 。

size

file.size()

返回文件的大小。

name

String name = file.name();

返回文件名。

close

file.close()

關(guān)閉并釋放文件對(duì)象。

在實(shí)際的運(yùn)用場(chǎng)景中,合理地使用SPIFFS會(huì)給我們省下很多的時(shí)間甚至是生產(chǎn)成本,希望這篇短文能給你在使用ESP8266的過程中給予一些幫助。

ESP8266 Core 參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容