
我個人很喜歡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的大小。


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()
返回真時就表示目錄枚舉完成。它的調用必須早於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的過程中給予一些幫助。
作者:梁睿坤
鏈接:https://www.jianshu.com/p/014bcae94c8b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。