RaspberryPi picoというのはRaspberryPi財団から出されているマイコンボードだ。550円という低価格ながら、クロック125MHzの32bitマイコンに264KBのRAM、2MBのFlashを載せており、大体のArduinoボードを凌駕する性能をしている。おまけに2コアだ。その内知見やライブラリが揃ってくれば、しょっぱい性能で数千円とるようなマイコンボードはpicoに蹂躙されることになるだろう。
こいつのプログラムはpico-sdkというSDKとC++を使って開発する。Python?犬にでも食わせておけ。
pico-sdkはCMakeを使ってコンパイルするようになっている。CMakeツールとArmコンパイラ(とnewlib)さえインストールされていればどこでもコンパイルできるのだ。素晴らしい!といいつつ、Windows環境との相性は非常に悪い。
純Windows環境でもがんばれば多分出来なくはないのだろうが、自分は諦めた。そして、WSL(Windows Subsystem for Linux)の上でやったら非常に楽に出来たのでその方法を紹介する。
WSLを使ってセットアップ
ほぼ公式のQuick Startに従うだけなので楽なこと極まりない。
- WSLのプロンプトを開く。
sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
する。- SDKのGitリポジトリをcloneし、そのパスをメモしておく。WSLの場合は「C:\hoge\foo\」みたいなパスではなく「/mnt/c/hoge/foo」みたいなパスになることだけ注意。
- 適当なところにプロジェクトのディレクトリを作り、中にpico_sdk_import.cmakeのコピーとソースコード(hello_world.cとする)、そしてCMakeLists.txtを作成する。
- ファイルの中身は以下とする。
// hello_world.c #include <stdio.h> #include "pico/stdlib.h" int main() { setup_default_uart(); printf("Hello, world!\n"); return 0; }
# CMakeLists.txt cmake_minimum_required(VERSION 3.13) # initialize the SDK based on PICO_SDK_PATH # note: this must happen before project() include(pico_sdk_import.cmake) project(my_project) # initialize the Raspberry Pi Pico SDK pico_sdk_init() # rest of your project add_executable(hello_world hello_world.c ) # Add pico_stdlib library which aggregates commonly used features target_link_libraries(hello_world pico_stdlib) # create map/bin/hex/uf2 file in addition to ELF. pico_add_extra_outputs(hello_world)
- ビルド用のディレクトリを作成する。パスは「(プロジェクトのディレクトリ)/build」とする。
- buildフォルダに移動し、cmakeする。このとき、オプションもしくは環境変数としてSDKのパスを指定しなければならない。
cmake .. -D PICO_SDK_PATH=(SDKのパス)
- makeすればhello_world.uf2が生成される。
- RaspberryPi picoをBOOTSELを押しながらPCに接続し、USBメモリと認識された状態で.uf2ファイルをドラッグ&ドロップすれば書き込み完了。
以上がWSLによるRaspberryPi pico開発環境構築方法だ。ここに書いたのは本当に公式のQuick Startのそのまま和訳みたいなものなので、WSLの最低限の知識があって英語が読める人は公式を読んだ方が良いと思う。
以下はおまけ兼、純Windowsでpicoの開発環境を整えようとしている人のための参考資料である。
純Windows環境を用いる(自分は諦めた)
一応途中までは進められたがそれ以上はどうにもならなかった。悔しいので作業記録を残しておく。
CMake、Make、Armコンパイラは普通にWindows環境で動くので、それを使ってもコンパイルできるはずである。また、Makeの代わりにNMake(Visual Studioに付属している)を使っても良い。
CMakeにはこのように素晴らしいツール代替性があるため、あっちでだめでもこっちならと様々な方法を試してみたものの、最終的にどれも同じ原因で無理だった。
Makeのインストール
GnuWin32のmakeのページで「Complete Package, except sources」からインストーラがダウンロードできるので、それを実行してインストールする。
標準ではC:\Program Files(x86)\GnuWin32\bin\にインストールされるが、C:\GnuWin32\bin\にインストールした方がいい。パスにスペースが入っていることが原因で死ぬ場合がある。スペースが入っていても問題は回避できるのかもしれないが、自分はその方法を見つけられなかった。
そして環境変数の設定。
- pathに C:\GnuWin32\bin\ を追加する。
- CMAKE_MAKE_PROGRAM=C:/GnuWin32/bin/make.exe を設定する。
多分CMAKE_MAKE_PROGRAMは必ずしも設定しなくても良いと思うが、make関連で変なエラーが出たら一応設定しておくと吉かもしれない。
CMakeのインストール
CMakeの公式HPの「Windows x64 Installer」もしくは「Windows i386 Installer」でインストーラがダウンロードできるので、それを実行してインストールする。
Armコンパイラのインストール
Armの公式HPからダウンロードする。「Windows (mingw-w64-i686) hosted cross toolchains」>「AArch32 bare-metal target (arm-none-eabi)」のところにインストーラやzipダウンロードの項目が並んでいるので、インストーラをダウンロードして実行する。
「AArch32」というのが32bit機向けコンパイラの意味で、「bare-metal target」というのがマイコンのような特にOSのない環境向けという意味なので他のものを選んではいけない。
デフォルトでは「C:\Program Files (x86)\Arm GNU Toolchain arm-none-eabi\(バージョン番号)\bin」にインストールされる。Makeと違い、こちらはどうやらパスにダブルクォーテーションを付けて実行されるようなので、パスにスペースが入っていることを心配する必要はあまりない。(というかなぜMakeではあんなことが起きたんだ?)
プロジェクトのセットアップ
Visual Studioを入れている人はとにかく注意。油断するとすぐarm-none-eabi-gccではなくMSVCが使われる。性質の悪いことに、-D CMAKE_C_COMPILERと-D CMAKE_CXX_COMPILERで指定するだけでは不十分だ。なぜかといえば、pico-sdkのcmakeファイルの仕様として、CMakeによって作られたMakeFileからさらにCMakeを実行するような入れ子構造があるためだ。このため外側で実行したCMakeがGCCを使用してくれても、内側のCMakeはMSVCを使いやがる。なので環境変数CCとCXXにarm-none-eabi-gccのパスとarm-none-eabi-g++のパスを指定する。
ちなみに恐怖のCMake入れ子構造があるため、何か変なことが起きたら即CMake生成ファイル群を丸ごと破棄して作り直した方が良い。どこに変な設定キャッシュが残っているか分かったものではない。
あと、環境変数CMAKE_TOOLCHAIN_FILEになんか設定している人は注意。自分はVCPKGの設定ファイルを設定していたのを忘れていて変な作用を起こしてしまった。なんかもうCMAKE関連の環境変数は全部注意。何が起きるか分からん。
そして色々問題点を潰した果て、自分はこの部分でにっちもさっちもいかなくなった。
ld.exeが「unrecognized option ‘–major-image-version’」というエラーを出す。
「–major-image-version」というオプションはどうやら、OS環境向けの一般的なGCCでは対応しているオプションなのだが、マイコンなどの非OS環境向けであるarm-none-eabi-gccでは対応していないオプションらしい。そして、どういうわけか知らないがWindowsでCMakeを動かすと勝手にこれを付けてgccを実行する。訳が分からない。
どうにかすればこのオプションを抑制できるのではないかと調べて回ったが検討が付かない。そもそもCMake自体の問題なのかどうかの検討すらつかない。ということで手詰まり。
StackOverflowに出ていたのでツールチェインファイルに「CMAKE_SYSTEM_NAME=Generic」とするなどもしてみたが無駄だった。解決策を持っている人がいたら教えて欲しい。