はじめに
Raspberry Pi Picoのファームウェアを開発する際の有力な選択肢として、PlatformIOでArduino-Picoを使用する方法が挙げられます。
Arduino-PicoをPlatformIO公式のRaspberry Pi Pico対応と合流させるPRは物別れに終わったようですが、依然、手軽かつ多機能な開発環境であることに変わりはありません。
Raspberry Pi Picoに搭載されているRP2040は、PIOという特徴的な機能を備えています。ここでは活用方法は紹介しませんが、大まかに言うと*.pio
のアセンブリ言語を記述し、pico-sdkに付属するpioasm
で*.pio.h
を生成して利用します。pico-sdkではCMake用の関数を提供していますが、PlatformIOでもビルド時に自動でPIOのアセンブリを行ってほしいものです。
Arduino-Picoはpico-sdkを丸ごと含んでおり、toos/pioasm
以下にpioasmのソースも含まれています。Windowsでこれらをビルドし、PlatformIOから利用する手順を紹介します。
MSYS2のセットアップ
pioasmには厄介な依存関係はありません。CMakeとお好みのコンパイラがあればビルドには苦労しませんが、特に用意していない場合はMSYS2を導入するのが最も手軽です。
C:\
直下にインストールすることを嫌うなら、自己解凍形式でダウンロードして環境一式を一つのフォルダに収めることもできます。私の好みはこちらです。
> Invoke-WebRequest -Uri https://github.com/msys2/msys2-installer/releases/download/2023-10-26/msys2-base-x86_64-20231026.sfx.exe -OutFile msys2-base-x86_64-20231026.sfx.exe
> .\msys2-base-x86_64-20231026.sfx.exe -y "-o$PWD\"
> cd .\msys64\
> .\msys2_shell.cmd -defterm -here -no-start -ucrt64
以降はMSYS2 UCRT64シェル上で作業します。まずはCMakeとMake、GCC等をインストールします。
$ pacman -Suy # コアシステムの更新が行われた場合はMSYS2シェルが終了するので、再度起動してもう一度`pacman -Suy`を実行する
$ pacman -S mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake
前者は多くのパッケージを含んでおり明らかに過剰ですが、ディスク容量が切羽詰まっていなければデフォルト=allのままで問題ないでしょう。Makeの実行ファイル名がmingw32-make.exe
であることに注意してください。
$ which cmake && which mingw32-make.exe && which gcc
/ucrt64/bin/cmake
/ucrt64/bin/mingw32-make.exe
/ucrt64/bin/gcc
pioasmのビルド
PlatformIOでArduino-Picoを使用したことがあるなら、$USERPROFILE/.platformio/packages/framework-arduinopico/pico-sdk/tools/pioasm
にソースコード一式がダウンロードされています。
ビルド手順自体は通常通りですが、MSYS2を削除しても動くように、CMakeLists.txtに静的リンクの設定を加えています。
$ cd $USERPROFILE/.platformio/packages/framework-arduinopico/pico-sdk/tools/pioasm
$ cp CMakeLists.txt _CMakeLists.txt
$ echo 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")' >> CMakeLists.txt
$ echo 'set(BUILD_SHARED_LIBS OFF)' >> CMakeLists.txt
$ echo 'set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")' >> CMakeLists.txt
$ cmake -S . -B build -G "MinGW Makefiles"
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
Compatibility with CMake < 3.5 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
-- The CXX compiler identification is GNU 13.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Users/mukai/msys64/ucrt64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (4.1s)
-- Generating done (0.0s)
-- Build files have been written to: C:/Users/mukai/.platformio/packages/framework-arduinopico/pico-sdk/tools/pioasm/build
$ cd build
$ mingw32-make all
[ 10%] Building CXX object CMakeFiles/pioasm.dir/main.cpp.obj
[ 20%] Building CXX object CMakeFiles/pioasm.dir/pio_assembler.cpp.obj
[ 30%] Building CXX object CMakeFiles/pioasm.dir/pio_disassembler.cpp.obj
[ 40%] Building CXX object CMakeFiles/pioasm.dir/gen/lexer.cpp.obj
[ 50%] Building CXX object CMakeFiles/pioasm.dir/gen/parser.cpp.obj
[ 60%] Building CXX object CMakeFiles/pioasm.dir/c_sdk_output.cpp.obj
[ 70%] Building CXX object CMakeFiles/pioasm.dir/python_output.cpp.obj
[ 80%] Building CXX object CMakeFiles/pioasm.dir/hex_output.cpp.obj
[ 90%] Building CXX object CMakeFiles/pioasm.dir/ada_output.cpp.obj
[100%] Linking CXX executable pioasm.exe
[100%] Built target pioasm
$ ./pioasm.exe -?
usage: pioasm <options> <input> (<output>)
Assemble file of PIO program(s) for use in applications.
<input> the input filename
<output> the output filename (or filename prefix if the output format produces multiple outputs).
if not specified, a single output will be written to stdout
options:
-o <output_format> select output_format (default 'c-sdk'); available options are:
ada
Ada specification
hex
Raw hex output (only valid for single program inputs)
python
Python file suitable for use with MicroPython
c-sdk
C header suitable for use with the Raspberry Pi Pico SDK
-p <output_param> add a parameter to be passed to the output format generator
-?, --help print this help and exit
PlatformIOのカスタムスクリプトを用意する
PlatformIOでは、ビルドの前後にPython(SCons)スクリプトを実行できるようになっています。
このスクリプト内ではインストール済みのPlatformIOパッケージのパスを取得する方法が提供されているため、framework-arduinopico
からたどって先ほどビルドしたpioasmを利用します。
[env:pico]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = pico
framework = arduino
board_build.core = earlephilhower
extra_scripts = pre:scripts/pioasm.py
import glob
import os.path
import pathlib
import sys
import warnings
Import("env")
PIO_FILES = glob.glob(os.path.join(env["PROJECT_SRC_DIR"], "*.pio"), recursive=True)
if len(PIO_FILES) != 0:
PIOASM_EXECUTABLE = (
pathlib.Path(env.PioPlatform().get_package_dir("framework-arduinopico"))
.joinpath("pico-sdk/tools/pioasm/build/")
.joinpath(f"pioasm{'.exe' if sys.platform.startswith('win') else ''}")
.resolve()
)
if PIOASM_EXECUTABLE.exists():
for filename in PIO_FILES:
env.Execute(f'"{PIOASM_EXECUTABLE}" -o c-sdk "{filename}" "{filename}.h"')
else:
warnings.warn(f'pioasm executable not found in "{PIOASM_EXECUTABLE}"', Warning)
ファームウェアをビルドすると、src
以下の*.pio
が処理され、対応する*.pio.h
が生成されるようになります。