ESP8266のSPIFFS機能


ESP8266ではSPIFFSと呼ばれるファイルシステムを使うことができます。
SPIFFSについてはこ ちらこ ちらで紹介されていますが、いずれもデータアップロードツールを使って
事前にファイルをアップロードし、アップロードしたファイルを読む内容です。

そこで、スケッチ内部でSPIFFS領域をフォーマットし、ファイルを読み書きする方法を紹介します。
以下にサンプルスケッチが紹介されていますが、少し変更しました、
http://www.esp8266.com/viewtopic.php?f=29&t=8194

SPIFFSのドキュメントは以下にあります。
http://esp8266.github.io/Arduino/versions/2.0.0/doc/filesystem.html

なお、SPIFFSを使うためにはArduino-IDEのツールメニューでFlush SizeにSPIFFSのサイズを指定する必要があります。
例えば、Flush Size:"4M(3M SPIFFS)"と指定すると3MのSPIFFSが使えます。
/*
* Basic SPIFFS Example
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
*/
#include "FS.h"

void listDir() {
  char cwdName[2];

  strcpy(cwdName,"/");
  Dir dir=SPIFFS.openDir(cwdName);
  while( dir.next()) {
    String fn, fs;
    fn = dir.fileName();
    fn.remove(0, 1);
    fs = String(dir.fileSize());
    Serial.println("<" + fn + "> size=" + fs);
  } // end while
}


void setup() {
  delay(500);
  Serial.begin(9600);
  Serial.println();

  Serial.println("\nVery basic Spiffs example, writing 10 lines to SPIFFS filesystem, and then read them back");
  SPIFFS.begin();
  // Next lines have to be done ONLY ONCE!!!!!When SPIFFS is formatted ONCE you can comment these lines out!!
  Serial.println("Please wait 30 secs for SPIFFS to be formatted");
  SPIFFS.format();
  Serial.println("Spiffs formatted");

  // open file for writing
  File fw = SPIFFS.open("/f.txt", "w");
  if (!fw) {
    Serial.println("file open failed");
  } else {
    Serial.println("====== Writing to SPIFFS file =========");
    for (int i=1; i<=10; i++){
      fw.print("Line : ");
      fw.println(i);
    } // end for
    fw.close();
  } // end if

  // list directory
  listDir();

  // open file for reading
  File fr = SPIFFS.open("/f.txt", "r");
  if (!fr) {
    Serial.println("file open failed");
  } else {
    Serial.println("====== Reading from SPIFFS file =======");
    for (int i=1; i<=10; i++){
      String s=fr.readStringUntil('\n');
      Serial.print(i);
      Serial.print(":");
      Serial.println(s);
    } // end for
    fr.close();
  } // end if


}

void loop() {
}

結果は以下の通りです。
10行のテキストファイルが作られていることが分かります。


実際に確保されているSPIFFSサイズは以下のスケッチで確認することができます。
#include "FS.h"

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  if (SPIFFS.begin() ) {
    //Serial.println("Please wait 30 secs for SPIFFS to be formatted");
    //SPIFFS.format();
    //Serial.println("Spiffs formatted");
    FSInfo fs_info;
    SPIFFS.info(fs_info);
    Serial.println("totalBytes:" + String(fs_info.totalBytes));
    Serial.println("usedBytes:" + String(fs_info.usedBytes));
    Serial.println("blockSize:" + String(fs_info.blockSize));
    Serial.println("pageSize:" + String(fs_info.pageSize));
    Serial.println("maxOpenFiles:" + String(fs_info.maxOpenFiles));
    Serial.println("maxPathLength:" + String(fs_info.maxPathLength));
  }
}

void loop() {
}

以下は4Mモジュールに対して、3MのSPIFFS領域を指定した時の実行結果です。
最大5個までのファイルを開くことができます。
totalBytes:2949250
usedBytes:0
blockSize:8192
pageSize:256
maxOpenFiles:5
maxPathLength:32

以下は4Mモジュールに対して、64KのSPIFFS領域を指定した時の実行結果です。
やはり、最大5個までのファイルを開くことができます。
調べてみましたが、maxOpenFilesはハードコードされているようです。
totalBytes:52961
usedBytes:0
blockSize:4096
pageSize:256
maxOpenFiles:5
maxPathLength:32

こちらで、RTCのユーザエリアはReset/Restartでも保持されるこ とを紹介しました。
そこで、Reset/RestartでSPIFFS上に作られたファイルが保持されるのかどうか、確認してみます。

続く....