Upgrade to Pro — share decks privately, control downloads, hide ads and more …

probe-rsの紹介と最近の貢献紹介/CELF-02-03

Toshifumi NISHINAGA
June 28, 2024
300

 probe-rsの紹介と最近の貢献紹介/CELF-02-03

Toshifumi NISHINAGA

June 28, 2024
Tweet

Transcript

  1. probe-rsとは • Rust製HWデバッガ制御ソフトウェア • https://github.com/probe-rs/probe-rs • マイコンのデバッグ機能を提供 • SWD/JTAGデバッガの制御 •

    gdb server機能 • RTT(RAM+デバッガ経由のログ出⼒機能) • 組み込みRustでよく使われる • VScode + probe-rs extension + probe-rs + defmt-rttの組み合わせが標準的 https://probe.rs/ top pageより引用
  2. probe-rsへの貢献 • 直近6件ほどマージしてもらった • https://github.com/probe-rs/probe-rs/pull/2208 • https://github.com/probe-rs/probe-rs/pull/2209 • https://github.com/probe-rs/probe-rs/pull/2269 •

    https://github.com/probe-rs/probe-rs/pull/2270 • https://github.com/probe-rs/probe-rs/pull/2271 • https://github.com/probe-rs/probe-rs/pull/2296 • v0.24.0でリリースされた • https://github.com/probe-rs/probe-rs/releases/tag/v0.24.0
  3. probe-rsに貢献した背景 • Raspberry Pi 5(arm64)でRTTを使いたい • Raspberry Pi 5ではDebuggerとUARTの端⼦が共⽤ かつ機能が排他

    • Debuggerを接続しつつログを⾒るためにRTTが使 えるかも? • arm64でRTT使えるソフトはなかった • arm64対応がない • pyOCD • arm64対応はあるけどRTTはマイコンのみ • OpenOCD, probe-rs • Rustで書きたい • probe-rsに貢献することに決定 • 開発初期はPi4、途中からPi5で検証 • arm64対応あるしすぐ終わると思っていた Pi 5のデバッグ端子 https://www.raspi.jp/2024/03/raspberry-pi-5- hardware-debbuging/ より引用
  4. MEMO: RTTとは • SEGGER社の作ったPC・マイコン間のデータ転送の仕組み • 正式名称はSEGGER Real Time Transfer(RTT) •

    https://wiki.segger.com/RTT • マイコン上のRAMをデバッガで読み書きしてデータをやり取りする • Rustではマイコンからのログに利⽤ • defmt + defmt-rtt crateでログをRTTで出⼒するのが標準的 • シリアルの接続不要で便利
  5. やったこと⼀覧 • 簡単なミスで動かない問題を修正 • https://github.com/probe-rs/probe-rs/pull/2208 • Pi5⽤の設定ファイルを追加 • https://github.com/probe-rs/probe-rs/pull/2209 •

    メモリアクセス時にCPUをHaltしない問題を修正 • https://github.com/probe-rs/probe-rs/pull/2269 • ELF64を読む機能を追加 • https://github.com/probe-rs/probe-rs/pull/2270 • メモリアクセスの⾼速化 • https://github.com/probe-rs/probe-rs/pull/2271 • 64bit targetのRTT実装の追加 • https://github.com/probe-rs/probe-rs/pull/2296
  6. Pi5⽤の設定ファイルを追加 • probe-rsは接続先情報をyamlファイルで管理する • Pi4⽤ファイルをベースにPi5⽤を作ってPRを出した • OpenOCDのように⾃作の外部ファイルを読み込んで使うことはできな さそうだった • 2024/06/29追記

    --chip-description-path オプションを使えばできそうでした • https://x.com/KOBA789/status/1806735675221541264 • https://github.com/probe-rs/probe-rs/pull/2209/files • これでPi5にattachできるようになった
  7. メモリアクセス時にCPUをHaltしない問 題を修正 • RTTのattach時にpanicした • 原因はCPUがHaltしていないのにメモリアクセスしたこと • Cortex-A系のCPUではHaltしていないとメモリアクセス不可 • https://speakerdeck.com/tnishinaga/kernelvm-online4

    • Cortex-M系はHaltしなくてもアクセスできる • バスの違いによるものらしい • APB(M系)は可能。AHB, AXIバス(A系)は不可 • https://wiki.segger.com/DAP • メモリアクセス処理前後にCPUをHaltするコードを追加 • https://github.com/probe-rs/probe-rs/pull/2269 • これでRTTでattachしてもpanicしなくなった
  8. ELF64を読む機能を追加 • arm64向けのELFバイナリをprobe-rs経由でPi4のメモリに転送 しようとしたができなかった • 「⾮対応バイナリです」みたいなことを⾔われた気がする • ELF64対応がなかったので追加した • https://github.com/probe-rs/probe-rs/pull/2270

    • probe-rsの使っているcrateがELF64対応していたので簡単だった • これでELF64を読み込めるようになった • が、probe-rsはFLASHへの書き込みをしない設定を想定してなくて、 やりたいことはできなかったので使っていない
  9. メモリアクセスの⾼速化 • Pi4のメモリ書き込みが2.3bpsしか出ない • 遅すぎてデバッガとして使えない • 原因 • USBの通信がネック •

    JTAGレベルで通信をまとめて⾏う機能はあった • DAP操作のコマンドをまとめて発⾏する機能がなかった • 遅い原因。治すのは⼤変 && Pi5のSWD接続では発⽣しない ので⼀旦放置 • 低速なメモリアクセス⽅法を使っていた • レジスタ経由の⽅法。これを改善した。 • 100倍⾼速化した • https://github.com/probe-rs/probe-rs/pull/2271 • やり⽅は以下を参照 • https://speakerdeck.com/tnishinaga/kernelvm-tokyo16 • これでデバッガとして使える速度になった ↑USBの通信待ちで JTAGのクロックが散発的な様子
  10. 64bit targetのRTT実装の追加 • probe-rsのRTT実装は32bitのみ対応 だった • メモリ上のRTT構造体のオフセットや サイズを定数決め打ちで扱う割り切っ た実装 •

    64bit対応するようデータ構造から作 り直した • genericsでu32/u64両対応させた構造 体を作成 • zerocopy crateでu8 sliceと相互変換 • https://github.com/probe-rs/probe- rs/pull/2296 • これでarm64でもRTTが読めるよう になった defmt側のRTT構造体 *const u8のサイズはターゲット依存 https://github.com/knurling-rs/defmt/blob/main/firmware/defmt- rtt/src/lib.rs#L124-L136
  11. 残った課題 • JTAG接続だと遅い問題 • DAPコマンドをQueueにためてまとめて発⾏する仕組みを作る必要がある • 修正規模がでかそうなので⼤変そう • レジスタがバグる問題 •

    ステップ実⾏すると何故かレジスタの値が壊れる • probe-rsはhalt直後にCPUレジスタ値を保存してresume時に書き戻す • armではデバッグ操作時にCPUレジスタを汚すため • 現状、保存のためレジスタ値を読み出す段階で壊れた値が返ってくる • その値をresume時にCPUに書き戻すのでレジスタ値が壊れる • 原因がわからない…… • Issueたててます。協⼒者募集中です。 • https://github.com/probe-rs/probe-rs/issues/2332