ESP32 SPIFFSを使ってみる

ESP32 SPIFFSを使ってみる

今回はSPIFFSを使ってみました。

この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。

投稿時の開発環境を記しておきます。

PC:
Windows10 OS

開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)

デバッガー(H/W):
FT2232D

デバッガー (S/W) :
Visual Studio Code + PlatformIO + ESP-IDF Framework

SPIFFSとは

SPIFFSは、組み込みターゲット上のSPINORフラッシュデバイスを対象としたファイルシステムです。

サイトのノートのところには以下の事柄が書かれています。

現在、SPIFFSはディレクトリをサポートしておらず、フラットな構造を生成します。
今のところ、不良ブロックを検出または処理しません。
SPIFFSは、割り当てられたパーティションスペースの約75%のみを確実に使用できます。

使える領域は確保した領域より少なめになるということのようです。

詳しくは ESP-IDF SPIFFS をご覧ください。

プロジェクトをつくる

使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。

その後にVSCodeからPlatformIOをOpenします。

以下の内容でプロジェクトを新規に作成します。

Name : ESP32E-spiffs
Board : Espressif ESP32 Dev Module
Framework : Eresspsif IoT Development Framework

Name : ESP32E の “E” は Framework (Espressif IoT Development Framework)の頭文字を示しています。

(後から見てわかるように、ESP-IDFを使うことを明示しています)

platformio.ini に以下の4行を追加して、 Ctrl + s で保存しておきます。

COM[4]の4の部分はデバイスマネージャーのポート(COMとLPT)で Silicon Labs CP210x から始まるCOMの番号を記述します。

debug_tool = minimodule
upload_port = COM[4]
monitor_speed = 115200
board_build.partitions = partitions_example.csv

一番下の行でパーティーションの割り当てを行います。
storageから始まる行で、spiffsの割り当てを行っています。
ここではサイズを1Mとしてみました。

この内容で CSVファイルを作成し、platformio.iniと同じフォルダに配置します。
ファイル名は上で指定した partitions_example.csv にします。

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x010000, 0x100000,
storage,  data, spiffs,  0x110000, 1M,

コンフィグレーション

sdkconfig.esp32devファイルに以下の3行を追加します。

CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"

サンプルプログラム

こちら を参考にしました。

コーディングする

以下のコードを main.c に貼りつけます。

#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_spiffs.h"

static const char *TAG = "spiffs";

void app_main(void)
{
    ESP_LOGI(TAG, "Initializing SPIFFS");

    esp_vfs_spiffs_conf_t conf = 
    {
      .base_path = "/spiffs",
      .partition_label = NULL,
      .max_files = 5,
      .format_if_mount_failed = true
    };

    esp_err_t ret = esp_vfs_spiffs_register(&conf);

    if (ret != ESP_OK)
    {
        if (ret == ESP_FAIL)
        {
            ESP_LOGE(TAG, "Failed to mount or format filesystem");
        }
        else if (ret == ESP_ERR_NOT_FOUND)
        {
            ESP_LOGE(TAG, "Failed to find SPIFFS partition");
        }
        else
        {
            ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
        }
        return;
    }

    size_t total = 0, used = 0;
    ret = esp_spiffs_info(conf.partition_label, &total, &used);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
    }
    else
    {
        ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
    }

    ESP_LOGI(TAG, "Opening file");

    FILE* fp = fopen("/spiffs/config.txt", "w");
    if (fp == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
    }
    fprintf(fp, "ip=192.168.5.11\n");
    fprintf(fp, "port=8080\n");
    fprintf(fp, "id=abcdefgh\n");
    fprintf(fp, "pass=stuvwxyz\n");
    fclose(fp);
    ESP_LOGI(TAG, "File written");

    fp = fopen("/spiffs/config.txt", "r");
    if (fp == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }

    char line[128];
    char *pos;

    while (fgets(line, sizeof(line), fp) != NULL)
    {
        pos = strchr(line, '\n');
        if (pos)
        {
            *pos = '\0';
        }
        ESP_LOGI(TAG, "Read from file: '%s'", line);
    }
    fclose(fp);
}

プログラムの説明

うまく動作すると、以下のログ出力の部分でパーティーションサイズを確認することができます。

ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);

その後に、config.txtというファイルに

ip, port, id, pass の定数を書いた後に読み出しています。

モニターにログを出力するので、うまく動作したら書いた値を読むことができます。

ビルドして実行する

ビルド後、エラーがないことを確認して F5キーを押して app_main() にカーソルが来るまで待ちます。

その後、F5キーを押してプログラムを実行します。

こちらの環境ではパーティーションサイズが以下のように表示されました。

example: Partition size: total: 956561, used: 1506␛[0m

その後もファイルを書いて読む動作を行っていますのでステップ実行しながら確認してみてください。
こちらのログは以下のようになりました。

␛[0;32mI (334) spiffs: Initializing SPIFFS␛[0m
␛[0;32mI (444) spiffs: Partition size: total: 956561, used: 1506␛[0m
␛[0;32mI (444) spiffs: Opening file␛[0m
␛[0;32mI (454) spiffs: File written␛[0m
␛[0;32mI (454) spiffs: Read from file: 'ip=192.168.5.11'␛[0m
␛[0;32mI (454) spiffs: Read from file: 'port=8080'␛[0m
␛[0;32mI (464) spiffs: Read from file: 'id=abcdefgh'␛[0m
␛[0;32mI (464) spiffs: Read from file: 'pass=stuvwxyz'␛[0m

不揮発性のメモリーに保存したい定数がある場合には手軽に使えそうですね。
ぜひ、お試しください。

SPIFFSカテゴリの最新記事