PlatformIO Tips
extra_scripts
の設定
ビルドの開始前に必要なファイルをコピーする実機のファイルシステム(LittleFSなど)にコピーするファイルをdata
フォルダに置きたいが,ビルドする対象によってファイルを変えたい場合などに使える。
copy_fiie.py
スクリプトを用意する。
Import("env")
import os
import shutil
file_from = os.path.normpath(env.GetProjectOption("custom_copy_file_from"))
file_to = os.path.normpath(env.GetProjectOption("custom_copy_file_to"))
print("Copy %s to %s" % (file_from, file_to))
shutil.copyfile(file_from, file_to)
platformio.ini
に以下の設定を追加。ファイルの相対パスはプロジェクトディレクトリが起点になる。ここではscripts/copy_file.py
に置くことを想定している。
[env:sample]
custom_copy_file_from = examples/Deepest/sound-effect-bin.wav
custom_copy_file_to = data/sound-effect.wav
extra_scripts = pre:scripts/copy_file.py
pre
を指定しているので,ビルドを実行してすぐにスクリプトが起動する。
Processing example (platform: espressif32@6.3.2; framework: arduino; board: m5stack-atom)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
Copy examples\Deepest\sound-effect-bin.wav to data\sound-effect.wav # スクリプト実行
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/m5stack-atom.html
PLATFORM: Espressif 32 (6.3.2) > M5Stack-ATOM
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
ファームウェアにバイナリを埋め込む
WAVやMP3などに音源ファイルを利用する際,ファイルシステム(LittleFSなど)に置いて読み込んだり,ソースコードに変換してファームウェアに埋め込む手法[1]があるが,PlatformIOのboard_build.embed_files
に指定するとファームウェアの.rodata
(Read Only Data)セクションに埋め込むことができる[2]。
board_build.embed_files = data/sound-effect.wav
ソースコードで参照する場合は,開始位置をasm(_binary_シンボル名_start)
,終了位置をasm(_binary_シンボル名_end)
で取得する。シンボル名は指定した名前の記号をすべて_
に置換した形になる。例えば,上の例は開始位置が「_binary_data_sound_effect_wav_start
」,終了位置が「_binary_data_sound_effect_wav_end
」になる。
extern const uint8_t SOUND_EFFECT_WAV_START[] asm("_binary_data_sound_effect_wav_start");
extern const uint8_t SOUND_EFFECT_WAV_END[] asm("_binary_data_sound_effect_wav_end");
static const size_t SOUND_EFFECT_WAV_SIZE = (SOUND_EFFECT_WAV_END - SOUND_EFFECT_WAV_START);
ちなみにboard_build.embed_txtfiles
を使うとテキストファイルを埋め込むことができる。board_build.embed_files
との違いは,Null終端が付加されるかどうかである。
参考文献
- M5Stack ATOM EchoにWaveファイルを埋め込んで再生する(2020年6月15日 Lang-ship)
- Embedding Binary Data(Espressif Systems)
ファイルシステムにファイルを転送する
SPIFFSやLittleFSなどのファイルシステムにファイルを転送するには,platformio.ini
のenv
セクションでdata_dir
に指定したフォルダ(デフォルトではdata
フォルダ)にファイルを置いて,PlatformIOメニュー(図1)のPROJECT TASKにある「Upload Filesystem Image」を選択する。
[platformio]
data_dir = data
図1:PlatformIOメニュー
例えば,/data/hoge.png
をUpload Filesystem Imageを選択して転送すると,プログラムからは/hoge.png
でアクセスできるようになる。
PlatformIO CLIで以下のコマンドを入力してアップロードすることもできる。
pio run --target uploadfs
参考
- SPIFFS Filesystem(Espressif Systems)
-
data_dir
(PlatformIO)
ターミナルからPlatformIO CLIを起動できるようにする
Windows
環境変数PATH
に%USERPROFILE%\.platformio\penv\Scripts
を追加する。
macOS・Linux
環境変数PATH
に$HOME/.local/bin
を追加する。
export PATH=$PATH:$HOME/.local/bin
必要なファイルから$HOME/.local/bin
へシンボリックリンクをはる。
ln -s ~/.platformio/penv/bin/platformio ~/.local/bin/platformio
ln -s ~/.platformio/penv/bin/pio ~/.local/bin/pio
ln -s ~/.platformio/penv/bin/piodebuggdb ~/.local/bin/piodebuggdb
参考
- Install Shell Commands(PlatformIO)
platformio.ini
の設定内容を確認する
プロジェクトフォルダ(platformio.ini
があるフォルダ)でpio project config
を実行する。-d
でプロジェクトフォルダを指定することもできる。
$ pio project config --help
Usage: pio project config [OPTIONS]
Options:
-d, --project-dir DIRECTORY
--lint
--json-output
-h, --help Show this message and exit.
$ pio project config
Computed project configuration for C:\home\saito\src\the-deepest-offertory-box
platformio
----------
default_envs = firmware-release
data_dir = C:\home\saito\src\the-deepest-offertory-box\data
env
---
platform = espressif32@6.3.2
platform_packages = platformio/tool-esptoolpy@1.40501.0
platformio/framework-arduinoespressif32@3.20011.230801
framework = arduino
board = m5stack-atom
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.mcu = esp32
board_build.flash_mode = dio
board_build.partitions = no_ota.csv
lib_deps = M5Unified@0.1.8
lib_ldf_mode = deep
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
time
upload_speed = 1500000
custom_firmware_version = 0.0.2
custom_firmware_name = the_deepest_offertory_box_firmware
custom_firmware_suffix = .bin
custom_firmware_dir = firmware
tof
---
lib_deps = M5Unified@0.1.8
https://github.com/pololu/vl53l0x-arduino
debug
-----
build_type = debug
build_flags = -DCORE_DEBUG_LEVEL=4
-DDEBUG
firmware
--------
build_flags = -DDISTRIBUTION_FIRMWARE
board_build.embed_files = data/sound-effect.wav
extra_scripts = post:generate_user_custom.py
env:firmware-release
--------------------
extends = tof
firmware
build_flags = -DCORE_DEBUG_LEVEL=3
-DDISTRIBUTION_FIRMWARE
custom_firmware_version = 0.0.2_release
board_build.embed_files = data/sound-effect.wav
extra_scripts = post:generate_user_custom.py
lib_deps = M5Unified@0.1.8
https://github.com/pololu/vl53l0x-arduino
platform = espressif32@6.3.2
platform_packages = platformio/tool-esptoolpy@1.40501.0
platformio/framework-arduinoespressif32@3.20011.230801
framework = arduino
board = m5stack-atom
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.mcu = esp32
board_build.flash_mode = dio
board_build.partitions = no_ota.csv
lib_ldf_mode = deep
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
time
upload_speed = 1500000
custom_firmware_name = the_deepest_offertory_box_firmware
custom_firmware_suffix = .bin
custom_firmware_dir = firmware
env:firmware-debug
------------------
extends = tof
firmware
debug
build_flags = -DDISTRIBUTION_FIRMWARE
-DCORE_DEBUG_LEVEL=4
-DDEBUG
custom_firmware_version = 0.0.2_debug
build_type = debug
board_build.embed_files = data/sound-effect.wav
extra_scripts = post:generate_user_custom.py
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.mcu = esp32
board_build.flash_mode = dio
board_build.partitions = no_ota.csv
lib_ldf_mode = deep
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
time
upload_speed = 1500000
custom_firmware_name = the_deepest_offertory_box_firmware
custom_firmware_suffix = .bin
custom_firmware_dir = firmware
platformio.ini
の設定が正しいかどうか確認したい場合はpio project config
に--lint
を付けて実行する。例えば,platformio
セクションでしか指定できないdata_dir
をenv
セクションで指定した場合には以下のように表示される。
$ pio project config --lint
Warning Ignore unknown configuration option `data_dir` in section [env]
extends
で重複した設定項目をマージする
セクションや環境をextends
した際に設定項目が重複すると,設定値がマージされずに後からextends
した値でどんどん上書きされていきます(extendsの説明の「警告」を参照)。
以下の例だとlib_deps1
のlib_deps
の値は,その後にextends
されるlib_deps2
のlib_deps
の値で上書きされます。
[base]
platform = teensy
framework = arduino
board = teensy31
[lib_deps1]
lib_deps =
monstrenyatko/ArduinoMqtt @ ^1.5.1
bblanchon/ArduinoJson @ ^6.18.3
knolleary/PubSubClient @ ^2.8
[lib_deps2]
lib_deps =
sstaub/Ticker @ ^4.3.0
thijse/ArduinoLog @ ^1.1.1
adafruit/RTClib @ ^1.14.0
[env:final]
extends = base, lib_deps1, lib_deps2
; `lib_deps1`の値は`lib_deps2`の値で上書きされるため,最終的に`lib_deps`は以下と同じになります。
; lib_deps =
; sstaub/Ticker @ ^4.3.0
; thijse/ArduinoLog @ ^1.1.1
; adafruit/RTClib @ ^1.14.0
このとき,extends
で重複する設定値を明示的に指定することでマージすることができます。
[env:final]
extends = base, lib_deps1, lib_deps2
lib_deps = ${lib_deps1.lib_deps} ${lib_deps2.lib_deps}
; 以下と同じになります。
; lib_deps = monstrenyatko/ArduinoMqtt @ ^1.5.1
; bblanchon/ArduinoJson @ ^6.18.3
; knolleary/PubSubClient @ ^2.8
; sstaub/Ticker @ ^4.3.0
; thijse/ArduinoLog @ ^1.1.1
; adafruit/RTClib @ ^1.14.0
参考
- extends(PlatformIO)
M5Stackに必要な基本ライブラリ・ツールのバージョン指定方法
バージョン指定は@
,指定したバージョン以降の場合は@^
で指定する。
2024年9月28日(土)現在の最新版を指定する場合は以下のようになる。
[env]
platform = espressif32@6.9.0
platform_packages =
platformio/framework-arduinoespressif32@3.20017.0
platformio/tool-esptoolpy@1.40501.0
platformio/espressif32
- Espressif開発プラットフィーム
- https://github.com/platformio/platform-espressif32
[env]
platform = espressif32@6.9.0 ; Espressif 32 v6.9.0
platformio/framework-arduinoespressif32
- ESP32用Arduino Coreライブラリ
- https://github.com/espressif/arduino-esp32.git
[env]
platform_packages = platformio/framework-arduinoespressif32@3.20017.0 ; arduino-esp32 v2.0.17
platformio/tool-esptoolpy
esptool.py
- https://github.com/espressif/esptool.git
[env]
platform_packages = platformio/tool-esptoolpy@1.40501.0 ; esptool v4.5.1
複数のサンプルプログラムを環境を切り替えてコンパイルする
+-- project
+-- .pio
+-- .vscode
+-- examples
| +-- example01
| | +-- main.cpp
| +-- exampl02
| +-- main.cpp
+-- include
| +-- Hoge.hpp
+-- src
+-- Hoge.cpp
上記の構成になっているライブラリでexample01
とexample02
をコンパイルできるようにするには,platformio.ini
を以下のように指定する。
build_src_filter
はsrc_dir
(デフォルトではsrc
)からの相対パスで指定する。
[env]
build_src_filter =
+<*.cpp>
+<*.hpp>
[env:example01]
build_src_filter =
${env.build_src_filter}
+<../examples/examples/example01/main.cpp>
[env:example02]
build_src_filter =
${env.build_src_filter}
+<../examples/examples/example02/main.cpp>
firmware.map
が見つからないと言われる
リンク時にファームウェアをリンクする際にマップファイル(firmware.map
)が開けないと言われる。エラーを見るとfirmware.map
が見つからないと表示されている。
Linking .pio\build\m5stack-stamps3\firmware.elf
c:/users/saito/.platformio/packages/toolchain-xtensa-esp32s3@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld.exe: \
cannot open map file C:/Users/saito/デスクトップ/m5stack-platformio-boilerplate-code/.pio/build/m5stack-stamps3/firmware.map: No such file or directory
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\m5stack-stamps3\firmware.elf] Error 1
ソースコードを置いているフォルダのパスにASCIIではない文字(日本語など)やスペースがある場合にPlatfromIOがfirmware.map
を見つけられずにエラーになる。上記の場合,C:\Users\saito\デスクトップ
という日本語が含まれるパスに置いているため,エラーになっている。
ASCIIではない文字やスペースがない場所にソースコードを置くことで回避できる。
PlatformIOでinoファイルをコンパイルする
PlatformIOではsrc_dir
(デフォルトではsrc
)で指定したディレクトリ直下にあるinoファイルのみino.cpp
に変換してコンパイルするため,Arduinoライブラリのexamplesをコンパイルする場合はsrc_dir
をexamples以下にする必要がある。
実際に変換された場合の表示は以下のようになる。
PACKAGES:
- framework-arduinoespressif32 @ 3.20014.231204 (2.0.14)
- tool-esptoolpy @ 1.40501.0 (4.5.1)
- toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
- toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5
Converting encoder.ino
参考
SPIFFSからLittleFSへの移行
特にツールを入れずにファイルイメージを作って実機にアップロードできる。
-
platformio.ini
の[env]
セクションに以下を追加する。[env] ... board_build.filesystem = littlefs
- ソース内の
SPIFFS
をLittleFS
に置換する。 - ファームをビルドしてアップロードする。
- PlatformIOメニューから
Upload Filesystem Image
を選択するか,コマンドラインからpio run --target uploadfs
を実行する。
参考
-
LITTLEFS_PlatformIO(arduino-esp32のGitHubリポジトリにある例)
※このやり方は古いので注意 - ダイヤル解錠トリガーをSPIFFSからLittleFSに移行した際の差分(ダイヤル解錠トリガーのGitHubリポジトリ)