YU2TA7KA's BLOG ~take one step at a time~

派生開発、組み込み開発周りのこと。

【組込みRust】組込みRustのデバッグアダプタ環境を構築する

はじめに

先日、RustでRaspberry Pi PicoをLチカすることができました。このときは、ターゲットのPicoへ直接FWを書き込む手順で実現しました。今回は、Picoをもう一台用意(合計2台)し、ターゲット用Picoとデバッグアダプタ用Picoの構成で動作させます。
これにより、デバッグ用の文字出力ができるようになります。エラー時にスタックトレースも出してくれるようになります。

はじめに - RustyKeys ビルドガイド
こちらの手順を参考にさせていただき、実施しました。基本的に手順内容は上記からの抜粋になります。

手順

1. HWの準備

Raspberry Pi Pico2台をはんだづけ(ブレッドボードに差し込むためには細ピンヘッダではんだづけする必要があります。)し、デバッグ関連のピンを以下のように配線します。ターゲット側は短辺の3つの端子になります。

ターゲット デバッグアダプタ
SWDIO GPIO4
GND GND
SWCLK GPIO2

ブレッドボード上のPico:ターゲット
床にあるPico:デバッグアダプタ用

2. 必要なパッケージのインストール

開発PCの環境を構築します。

# Raspberry Pi Pico(Cortex M0)向けのターゲット追加
$ rustup target add thumbv6m-none-eabi
# elf2uf2-rs, probe-run用に必要なパッケージ([https://github.com/knurling-rs/probe-run#installation])
$ sudo apt install -y libusb-1.0-0-dev libudev-dev
# ELFからUF2形式への変換ツール
$ cargo install elf2uf2-rs
# バイナリの転送と実行をするためのツール。(Raspberry Pi Pico のデバッグ出力を開発環境のコンピュータに表示する機能もあります。)
$ cargo install probe-run
# メモリ配置変換ツール
$ cargo install flip-link
# テンプレートからRustのプロジェクトを生成するCargoサブコマンド
$ cargo install cargo-generate

3. デバッグアダプタ用PicoのFW更新

片方のPicoをデバッグアダプタとして動作させるため、そのように動いてくれるFWを書き込み込みます。

# デバッグアダプタFWのリポジトリ取得
$ git clone https://github.com/ciniml/rust-dap.git
# ディレクトリ移動
$ cd rust-dap/boards/xiao_rp2040
# FWのビルドと書き込み 実行前にPico1台をPCに接続し、USBストレージとして認識させておく(BOOTSELボタンを押しながらPCへ接続)必要があります。
$ cargo run --release

コマンドの実行が完了し、LED が点灯していればOKです。

4. ターゲット用PicoのFW更新(Hello World)

デバッグアダプタ経由でターゲット用PicoのFWを更新し、PC端末上にHello Worldの文字列を出力させます。

# Hello World(rusty-keys)のリポジトリ取得
$ git clone https://github.com/KOBA789/rusty-keys.git
# ディレクトリ移動
$ cd rusty-keys/firmware/hello
# ターゲット(Hello World)FWのビルドと書き込み 実行前にデバッグアダプタ用Pico、ターゲット用Picoの順番にPCへ接続する必要があります。接続の順番が逆だと失敗します。BOOTSELボタンを押しておく必要はありません。
$ cargo run


これでデバッグアダプタを接続した状態で組込みRustの開発ができます!

詰まったところ

デバッグアダプタ用のFWを書いていなかった

私は、手順3を忘れて手順4を実施していました。その際、下記エラー文がでました。

yu2ta7ka@yu2ta7ka-H110M-S01:~/code/Rust/pico/rusty-keys/firmware/hello$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `probe-run --chip RP2040 target/thumbv6m-none-eabi/debug/rusty-keys-hello`
Error: no probe was found.

Common reasons for this are faulty cables or missing permissions.
For detailed instructions, visit: https://github.com/knurling-rs/probe-run/tree/2f138c3#troubleshooting

エラー文より、デバイスアクセスに対して、rootユーザー以外のアクセス権付与(udev設定)設定が必要と考えました。下記いくつかの記事においてもudev設定が必要ということで、ここらへんかなと思いいろいろudevのruleファイルをいじりました*1。しかし、私の環境はUbuntuですが、ruleファイル無くても、Hello Worldできたので、無関係でした。
Embedded-Rust-from-Basics/debug at main · tomoyuki-nakabayashi/Embedded-Rust-from-Basics · GitHub
Installation Instructions - Workbook for Embedded Workshops

結局は、デバッグアダプタ用のFWを書かないで動作させようとしていたことが問題でした。手順3を実施することで本問題は解消されました。勝手にHello WorldのFWを書くタイミングでデバッグアダプタ用のFWもよしなにやってくれるだろうと勘違いしていました。(probe-run関連のドキュメント見ながら)よく考えると、勘違いに気づけました。以下のFW構成のイメージができれば良かったのだろうと思います。

(Pico内でブートプログラムがどのように実装されているかは未調査ですが、更新しているFWを起動するためのブートプログラムが存在しているだろうと思っています。)

動作手順が少し複雑

デバッグアダプタ用FWが正しく書けていたとしても動作手順が少し複雑と思いました。2点あって、1点目がデバッグアダプタ用Pico、ターゲット用Picoの順番にPCへ接続する必要があることです。接続の順番が逆だと失敗します。加えて、BOOTSELボタンを押しておく必要はないことです。BOOTSELボタンを押すとデバッグアダプタ用FWが起動しないのだと思います。2点目がPCへPicoを接続して少し時間が経過してからFW書き込み(cargo run)をする必要があるようです。接続して直後にコマンド(cargo run)を実行すると失敗します。そして、再度コマンドを実行すると正常に書き込めます。以上2点が少し複雑な点でした。

おわりに

詰まった点がありましたが、デバッグアダプタ環境ができました。次は、rusty-keysを使わせてもらい、タクトスイッチをキーボードとして制御するようにしてみたいと思います。また、gdbを利用したデバッグ環境構築までやりたいです。ここもドキュメントちゃんと読んで完了できればと思います。

追記(2022年8月14日)

「デバッグアダプタ用のFWを書いていなかった」の項目でruleファイルが無関係と記載しました。しかし、改めてUbuntu環境でキーボードFWの実装を試していたら、以下のudev rulesの3つの手順は必要でした。
Probe Setup | probe-rs

*1:TAG+="uaccess"が必要な環境もあるのかなと思います。