Raspberry Pi Pico を WSL からあつかう


1月にRaspberry Pi Pico が発表され、2月に入ると国内でも入手が可能になりました。

StartingガイドもあるのでLチカくらい余裕だろ、と思ってましたが WSL (Windows Subsystem for Linux) 上の Ubuntu から使えるようにするのに Windows 用のガイドも Mac用のガイドも微妙に役立たないので記事として残します。

なお、C/C++ SDKを使ってビルドすることを対象にしています。MicroPython は対象としていません。

環境

  • Windows 10 Home 64bit (20H2)
  • WSL: Ubuntu-18.04

必要ツールをビルドするのに多少パワーが必要ですがのんびり待てば終わります。

コードの編集は VSCode (現時点では 1.53)を使いますが、まずは WSL の shell からサンプルをビルド、uf2 をターゲットに転送するまでを目標としています。

インストール手順

公式ドキュメント(Getting started with Raspberry Pi Pico)では、

  • Raspberry Pi 4/400
  • Windows OS
  • Mac OS

を対象にして説明されています。Windows のコマンドプロンプトではなく WSL の shell からツール類を扱うためには、以下の環境で可能でした。

  • arm gcc compiler
  • cmake (3.13以上を要求)
  • gcc
  • python 3.7
  • git

ここで、Ubuntu-18.04 のパッケージでは python が3.6、cmake が 3.10 が最新であるためか、これより新しいバージョンを使用するには一工夫が必要でした。arm-gcc, gcc, git は最新版を入れれば問題ないようです。

arm gcc compiler のインストール

apt-get で gcc-arm-none-eabi をインストール。

$ sudo apt-get install gcc-arm-none-eabi
...
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:6.3.1+svn253039-1build1) 6.3.1 20170620

python 3.7 のインストール

python3 のバージョンが3.7以上であればOK。それより低い場合はインストールが必要。

$ sudo apt-get install python3.7

もしビルド時に python 関連でエラーになるようなら /usr/bin/python でアクセスできるようにしてやればいいらしい。
が、ドキュメントでは必要ない、となっている

$ sudo ln -s /usr/bin/python3.7 /usr/bin/python

※ただし、これをすると他の python 使ったプロジェクトでエラーになるかも知れないので注意

git のインストール

githubからSDKの取得に必要。WSL環境に必須ではない。

$ sudo apt-get install git
...
$ git --version
git version 2.17.1

gcc のインストール

ドキュメントでは、「Build Tools for Visual Studio 2019」とありますが、 pico-sdk に含まれる、 pioasmelf2uf2 というコマンドラインツールがビルドできれば良いようなので、gcc で。

$ sudo apt-get install gcc
...
$ gcc -version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

cmake のインストール

ドキュメントでは cmake のバージョンは指定されていませんが、Ubuntu-18.04 の cmake の最新パッケージは 3.10 で、これではサンプルのビルドに cmake 3.13 以上を要求されてサンプルがビルドできませんでした。

面倒なので Cmake を自前でビルドしてインストールします。

CMakeの最新バージョンをUbuntu18.04.4 LTSにインストール - Qiita を参考にソースと依存ライブラリである openSSL をインストールしビルドしました。

  • 公式サイトから cmake のソース (CMake 3.19.4)
  • OpenSSL development package

※なお、cmake は /usr/local/bin にインストールし、古い cmake は削除しています

$ cmake --version
cmake version 3.19.4

SDK とサンプルのインストール

ドキュメントに従い、インストール

$ cd <picoのSDK/sampleをインストールするフォルダ>
$ git clone -b master https://github.com/raspberrypi/pico-sdk.git
$ cd pico-sdk
$ git submodule update --init
$ cd ..
$ git clone -b master https://github.com/raspberrypi/pico-examples.git

環境変数 PICO_SDK_PATHpico-sdk をインストールしたパスを設定する
※絶対パスが必要

.bashrc
export PICO_SDK_PATH=/<picoのSDK/sampleをインストールしたフォルダ>/pico-sdk

コマンドラインから "Hello World" をビルドする

$ cd pico-examples
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" ..
$ make
$ ls -F
$ ls -F
CMakeCache.txt*  clocks/               elf2uf2/      i2c/        pio/     spi/     watchdog/
CMakeFiles/      cmake/                flash/        interp/     pioasm/  system/
Makefile*        cmake_install.cmake*  generated/    multicore/  pwm/     timer/
adc/             divider/              gpio/         pico-sdk/   reset/   uart/
blink/           dma/                  hello_world/  picoboard/  rtc/     usb/

サンプルに対応して、buildフォルダ下に .uf2 ファイルが作成されている

$ ls blink/
CMakeFiles  blink.bin  blink.elf      blink.hex  cmake_install.cmake
Makefile    blink.dis  blink.elf.map  blink.uf2  elf2uf2

Raspberry Pi Pico に作成した uf2 ファイルを書き込む

USBケーブルを接続した Pico を、部品面にあるボタン(BOOTSEL button)を押しながら PC に接続すると(取り付け後ボタンを離す)、PCからUSBストレージモードとして見えるようになります。

作成した .uf2 ファイルをエクスプローラーからドラッグ・アンド・ドロップすれば書き込み終了後に Pico が再起動し、書き込んだプログラムが実行されます。

…しかし WSL 使ってるのに GUI 使うのもなあ、というところなので、コマンドラインで済ませたいところです。WSL から Windows のファイルシステムをマウントするには drvfs というファイルシステムを指定すれば可能ですが、USBメモリなどを mount したまま umount せずに取り外すと再 mount がうまく行かない、ということがありまして頻繁に取り外しが発生するであろうこの環境では躊躇します。
そこで cmd.exe 経由でコピーさせるとうまくいきました。

$ uf2=build/blink/blink.uf2; cmd.exe /d /c copy /b $(wslpath -a -w $uf2) F:\\

(bash使用。FドライブにPicoが接続されています)

なお、USBストレージモードでPCに接続するとルートディレクトリに INFO_U2.TXT というファイルが有ります。

$ cmd.exe /c type F:\\INFO_UF2.TXT
UF2 Bootloader v1.0
Model: Raspberry Pi RP2
Board-ID: RPI-RP2

このファイルを検索してデバイスが見つかればコピーする、とようなバッチファイルを準備してやればちょっとイカス環境に。
バッチファイルで複雑なことが出来ないので bash で書きました

tr_uf2
#!/bin/bash
# tr_uf2 <.uf2 file>

uf2=$1
if [ a"$uf2" = a"" ]; then
    # 何もしない
    echo "Usage: tr_uf2 <.uf2 file>"
    exit 1
fi

# ドライブレターぶっこ抜き
# 改行文字削除
drv=$((cmd.exe /d /c for /f "tokens=1,* delims= " %c in \(\'fsutil fsinfo drives\'\) do @echo %d) | sed 's/[\r\n]\+//g')

# ドライブルートのファイル存在チェック
pico=$((for d in $drv; do (cmd.exe /d /c if exist "$d"INFO_UF2.TXT \( echo $d \) ); done) | sed 's/[\r\n ]\+//g')

if [ a"$pico" != a"" ]; then
    echo "copy: "$uf2
    cmd.exe /d /c copy /b $(wslpath -a -w $uf2) "$pico"
else
    echo "Not found Pico!"
    exit 1
fi