ESP-IDFを使ってみる

ファイルのアップロード


Arduino for esp32ではこ ちらのツールを使って、SPIFFSにファイルをアップロードすることができます。
ESP-IDFでもファームのビルド時に自動的にファイルをアップロードすることができます。

プロジェクトトップのCMakeLists.txtに以下を追加してファームをビルドします。
ファームのビルドと同時にdataディレクトリの内容がstorageパーティションにアップロードされます。
# Create a SPIFFS image from the contents of the 'font' directory
# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
# the generated image should be flashed when the entire project is flashed to
# the target with 'idf.py -p PORT flash
spiffs_create_partition_image(storage data FLASH_IN_PROJECT)

spiffs_create_partition_imageの書式はこ ちらに記載されています。

ファームを書き込むたびに、SPIFFSにアップロードを行うので、ファイルが大きいと書き込みに時間がかかります。
そこで、開発中は最初に一度だけspiffs_create_partition_imageを有効にして、ファイルを予めアップロードして置 き、開発中はアップロードを無効にしています。
必要なファイルをアップロードしておけば、ファームをビルドしてもパーティションの内容は保持されます。
テストが終わったらアップロードを再び有効にします。



こ ちらにSPIFFSパーテイションにファイルをアップロードするサンプルが公開されています。
spiffs_image内のファイルをビルドと同時にSPIFFSにアップロードします。
こちらがspiffs_imageの内容です。
$ ls -Rl
.:
合計 8
-rw-rw-r-- 1 nop nop   13  7月 19 08:27 hello.txt
drwxrwxr-x 2 nop nop 4096  7月 19 08:27 sub

./sub:
合計 168
-rw-rw-r-- 1 nop nop 169856  7月 19 08:27 alice.txt

実行すると、以下の様にhello.txtを読み込んで、sub/alice.txtのMD5 hashを計算します。
I (0) cpu_start: Starting scheduler on APP CPU.
I (340) example: Initializing SPIFFS
I (470) example: Partition size: total: 896321, used: 171935
I (470) example: Reading hello.txt
I (470) example: Read from hello.txt: Hello World!

I (470) example: Computing alice.txt MD5 hash
I (700) example: Computed MD5 hash of alice.txt: 79b45b0f4cb2098cc396da046db6da1f
I (700) example: SPIFFS unmounted

SPIFFSはディレクトリ操作をサポートしていません。
mkdir()/chdir()/rmdir()は使えません。
但し、スラッシュをファイル名の一部として使うことができます。
[sub/slice.txt]も[sub_slice.txt]と同様に、単純なファイル名として扱います。



こ ちらにFatFSパーテイションにファイルをアップロードするサンプルが公開されています。
ESP-IDF V5で追加されました。
FatFSのデフォルトは短いファイル名(8文字+3文字)ですが、以下を変更することで長いファイル名を使うことができるようになります。


デフォルトの短いファイル名の時は、fatfs_image内のファイルを、
長いファイル名の時はfatfs_long_name_image内のファイルをビルドと同時にFatFSにアップロードします。
こちらがfatfs_long_name_imageの内容です。
ファイルのタイムスタンプはリポジトリをクローンした時の日時(2022年 7月 19日)になっています。
$ ls -Rl
.:
合計 8
-rw-rw-r-- 1 nop nop   48  7月 19 08:27 hellolongname.txt
drwxrwxr-x 2 nop nop 4096  7月 19 08:27 sublongnames

./sublongnames:
合計 4
-rw-rw-r-- 1 nop nop 31  7月 19 08:27 testlongfilenames.txt

FatFSへの書き込みはfatfs_create_rawflash_image(Read Only)か、fatfs_create_spiflash_image(Read Write)を使います。
これらのコマンドの書式はこ ちらに記載されています。
PRESERVE_TIMEのフラグが有ると、ソース フォルダーからターゲット イメージへのタイムスタンプを強制的に保持することができます。
公式サンプルではCMakeLists.txtの中で以下の様にコマンドを実行しています。
if(CONFIG_EXAMPLE_FATFS_MODE_READ_ONLY)
    if(CONFIG_EXAMPLE_FATFS_DEFAULT_DATETIME)
        fatfs_create_rawflash_image(storage ${image} FLASH_IN_PROJECT)
    else()
        fatfs_create_rawflash_image(storage ${image} FLASH_IN_PROJECT PRESERVE_TIME)
    endif()
else()
    if(CONFIG_EXAMPLE_FATFS_DEFAULT_DATETIME)
        fatfs_create_spiflash_image(storage ${image} FLASH_IN_PROJECT)
    else()
        fatfs_create_spiflash_image(storage ${image} FLASH_IN_PROJECT PRESERVE_TIME)
    endif()
endif()

こちらが、PRESERVE_TIMEのフラグが無いときの出力です。
時刻を保持しないと、すべてのタイムスタンプが FATFS のデフォルトの初期時刻 (1980年 1月 1日) に設定されます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (330) example: Mounting FAT filesystem
I (340) example: Reading file
I (340) example: The file '/spiflash/sublongnames/testlongfilenames.txt' was modified at date: 1980-01-01
I (350) example: Read from file: 'this is test; long name it has'
I (360) example: Unmounting FAT filesystem
I (360) example: Done

こちらが、PRESERVE_TIMEのフラグが有るときの出力です。
ソース フォルダーのタイムスタンプが保持されています。
I (0) cpu_start: Starting scheduler on APP CPU.
I (330) example: Mounting FAT filesystem
I (340) example: Reading file
I (340) example: The file '/spiflash/sublongnames/testlongfilenames.txt' was modified at date: 2022-07-19
I (350) example: Read from file: 'this is test; long name it has'
I (360) example: Unmounting FAT filesystem
I (360) example: Done



こ ちらにHTTPを使ったファイルのアップロード、ダウンロードのサンプルが公開されています。
ブラウザーのアドレスバーにESP32のIPアドレスを指定すると、SPIFFSにあるファイルの一覧を表示します。


「ファイルを選択」ボタンを押すとファイル選択ダイアログが表示され、ホスト側のファイルを選ぶことができます。
「UPLOAD」ボタンを押すとESP32のSPIFFSにファイルをアップロードします。
この部分はビルド時に埋め込まれた「upload_script.html」を使っています。

「DELETE」ボタンを押すとSPIFFS上のファイルを削除します。
このボタンを押すと「http://IPアドレス/delete/ファイル名」のPOSTリクエストにより、 「delete_post_handler」が呼び出されます。

ファイル名のアンカーをクリックすると「http://IPアドレス/ファイル名」のGETにより、 「download_get_handler」が呼び出されます。

curlを使って以下のコマンドでファイルをSPIFFSにアップロードすることができます。
$ curl -X POST --data-binary @sdkconfig http://ESP32のIPアドレス/upload/sdkconfig

$ curl -X POST --data-binary @CMakeLists.txt http://ESP32のIPアドレス/upload/CMakeLists.txt

パーティションテーブルに変更が無ければ、別のファームを書き込んでも、SPIFFSはそのまま保持されます。
I (0) cpu_start: Starting scheduler on APP CPU.
I (338) example: Initializing SPIFFS
I (458) example: Partition size: total: 896321, used: 38905
I (518) example: d_name=sdkconfig d_ino=0 d_type=1 fsize=37805
I (518) example: d_name=CMakeLists.txt d_ino=0 d_type=1 fsize=230
I (558) example: SPIFFS unmounted

アドレスバーに[/favicon.ico]を指定するとアイコンイメージを表示します。
アイコンイメージはビルド時に埋め込まれています。
なかなかよくできたサンプルで、ESP-IDFでHTTPサーバを作るときには非常に参考になります。


続く...