1. 程式人生 > 其它 >ESP8266開發之旅 網路篇 SPIFFS——ESP8266 SPIFFS檔案系統

ESP8266開發之旅 網路篇 SPIFFS——ESP8266 SPIFFS檔案系統

技術標籤:esp8266SPIFFS檔案系統

  1. 前言
    在前面博文關於ESP8266WiFiWebServer的例程中,大家可以發現,博主基本上都是手動拼裝html內容返回,html的內容被固定寫在我們的Arduino ESP程式碼中。
    那麼這樣就有兩點弊端:

1.ESP8266程式碼相當臃腫
為了開發方便,web server網頁除了自身的html內容之外,還包括一些css檔案,甚至引入了JQuery庫以及一些圖片相關資源。如果把這些內容也直接寫入到ESP8266程式碼中,會導致8266整體程式碼變大,甚至可能超過flash規定的大小;
2.業務職責分離不明確
一般來說,在一個開發團隊中,有人負責開發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大類:

  1. SPIFFS專用方法
  2. Dir物件專用方法
  3. 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);

注意點:

1.路徑必須是以斜線開頭的絕對路徑(如:/dir/filename.txt);
2.模式引數是個用字串指定的存取模式,其值為“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);