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

RustでCMSIS-DAP実装してみた。

Kenta IDA
July 15, 2021
840

 RustでCMSIS-DAP実装してみた。

2021年7月15日のNature Bath vol.13で発表した 「RustでCMSIS-DAPじっそうしてみた。」トークの資料です。

タイトルの通り、RustでCMSIS-DAPを実装してみた経緯と感想について説明しています。

Kenta IDA

July 15, 2021
Tweet

Transcript

  1. 自己紹介 •井田 健太 (@ciniml) •仕事:FPGAの論理設計 •使用言語:C++, SystemVerilog, Rust, C# •組込みRust本の1割くらい書きました

    (サンプルアプリ作ったり、デバッガ試したり)→ 2021/7/15 Rust CMSIS-DAP で を実装してみた
  2. Wio Terminalとは? 2021/7/15 Rust CMSIS-DAP で を実装してみた • 組込みRust本でターゲットとしたマイコン・モジュール •

    液晶、ボタン、スピーカーが筐体に収まっている • メインCPUはArmコア • ATSAMD51P19A (Microchip) • Cortex-M4F@120MHz • 無線通信機能 (WiFi, BLE) もついてる • バッテリは含まず • LiPoの処分に困るので助かる
  3. CMSIS-DAP 2021/7/15 Rust CMSIS-DAP で を実装してみた •Cortex系プロセッサ内部のデバッグ機能に USB経由でアクセスするための仕様とファームウェア実装 • ホストとUSB経由で通信

    • ターゲットとJTAGもしくはSWDで通信 •Armが策定しており、仕様とソースコードが公開されている • 現在はGitHub上で管理されている • https://arm-software.github.io/CMSIS_5/DAP/html/index.html ホスト PC USBついてるArm MCU デバッグしたい Arm CPU CMSIS-DAP USB JTAG SWD
  4. Wio Terminalのデバッグ事情 2021/7/15 Rust CMSIS-DAP で を実装してみた •デバッグ用コネクタ • 0.5[mm]x10ピン

    FFCコネクタ • FFC+FFC変換基板でデバッガに接続 • どちらもAmazonやaitendoで買える • 機材リストはサポートページに記載 https://github.com/tomoyuki-nakabayashi/Embedded-Rust-from- Basics/tree/main/debug
  5. デバッグ用アダプタを作る 2021/7/15 Rust CMSIS-DAP で を実装してみた •USBついてるMCUがあれば作れる •今回は Seeeduino XIAOを使用

    • ATSAMD21G18 • USB2.0 FS •ファームは既存のもの • Seeedが移植している (のを改造したやつ) CMSIS-DAPファームウェア入り Seeeduino XIAO ホストPCの USBポートへ
  6. 既存CMSIS-DAPファームウェアの欠点 2021/7/15 Rust CMSIS-DAP で を実装してみた •Windowsへのインストールがメンドイ! • ベンダ固有クラスなのでドライバが必要 •

    Zadigを使ってドライバを導入する必要がある •挿しただけで動くようにしたい! • Zadigの手順書くのメンドイねん →WCIDの設定をしよう!
  7. WCID (Windows Compatibility ID) 2021/7/15 Rust CMSIS-DAP で を実装してみた •

    汎用USBドライバ(WinUSB)を 自動インストールするための仕組み • Microsoft OS Descriptor 2.0という仕様にしたがった ディスクリプタでデバイスがWinUSB対応であることを 表明できる • ファームウェア改造しよう! • SeeedのCMSIS-DAPファームウェアは 現行の構造上返せないことが判明 (残念…) →Rustで実装すればいいんじゃない? SeeedのCMSIS-DAPファーム =WCID非対応
  8. RustでCMSIS-DAPを実装する 2021/7/15 Rust CMSIS-DAP で を実装してみた •そもそも可能なのか? • Seeeduino XIAOのコードをRustで書けるか?

    →書ける • xiao_m0クレートを使えばいい • USBを扱うクレートはあるのか? →ある • usb-deviceクレート • xiao_m0クレートがusb-deviceクレート内のトレイトを実装している →実装しよう!
  9. 開発の流れ 2021/7/15 Rust CMSIS-DAP で を実装してみた •USBデバイスとしての機能を実装していく • usb_deviceクレートのUsbClassトレイトを実装するだけ •

    コンフィグレーション・ディスクリプタを返す • ストリング・ディスクリプタを返す • etc... •USBデバイス開発としてはかなり楽 impl<B: UsbBus> UsbClass<B> for CmsisDapInterface <‘_, B> { fn get_configuration_descriptors(...) {...} fn get_bos_descriptors(...) {...} fn get_string(...) {...} fn control_in(...) {...} ... }
  10. 動作確認 2021/7/15 Rust CMSIS-DAP で を実装してみた •OpenOCDで接続…うごいた! • プログラムの書き込み •

    実行・停止 • レジスタの内容取得 $ sudo ~/openocd-pico/bin/openocd -f interface/cmsis-dap.cfg -c "cmsis_dap_vid_pid 0x6666 0x4444" -f target/atsame5x.cfg ... Info : Using CMSIS-DAPv2 interface with VID:PID=0x6666:0x4444, serial=test Info : CMSIS-DAP: SWD Supported Info : CMSIS-DAP: FW Version = 2.00 Info : CMSIS-DAP: Serial# = Piyo Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0 Info : CMSIS-DAP: Interface ready Info : clock speed 2000 kHz Info : SWD DPIDR 0x2ba01477 // SWDでターゲットと通信して読んだ値 Info : atsame5.cpu: hardware has 6 breakpoints, 4 watchpoints Info : starting gdb server for atsame5.cpu on 3333 Info : Listening on port 3333 for gdb connections $ gdb-multiarch 8-2-mic_fft // 組込みRust本のスペアナサンプル (gdb) load // WioTerminalに書き込み ... Transfer rate: 19 KB/sec, 8730 bytes/write. // 19[KB/s]なのでまあまあ実用的 (gdb) monitor reset halt target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x0000056c msp: 0x2000d6a0 (gdb) cont Continuing. ^C ... (gdb) info reg // レジスタ読み出し r0 0x6 6 r1 0x19f1 6641 ... pc 0x75fe 0x75fe <embedded_graphics::pixelcolor::conversion::<impl core::convert::From<embedded_graphics::pixelcolor::rgb_color::Rgb888> for embedded_graphics::pixelcolor::rgb_color::Rgb565>::from+64> xPSR 0x41000000 1090519040 ...
  11. 動作確認 (Windows) 2021/7/15 Rust CMSIS-DAP で を実装してみた •WCID対応→OK • WINUSBと互換性アリ

    •実際にWinUSBドライバが ロードされている Rust実装版CMSIS-DAP =WCID対応
  12. 実装してみて感じたRustの便利なところ 2021/7/15 Rust CMSIS-DAP で を実装してみた •cargo便利 • 外部ライブラリの導入が用意 •

    C/C++だとライブラリ入れるの面倒なので… •ハードウェアの抽象化が良くできている • usb-deviceクレートを使えば驚くほど簡単にUSBデバイスが作れる • usb-deviceクレートを使って汎用のCMSIS-DAP実装 • XIAO以外のハードでも動作するはず • そのうちRaspberry Pi Picoあたりで試したい
  13. 実装してみて感じたRustの便利なところ 2021/7/15 Rust CMSIS-DAP で を実装してみた •Result<T, E>でのエラー伝搬が楽にできる • C++だと例外だが、

    組込みC++の場合は無効化されることが多い • スタック巻き戻しのための諸々のオーバーヘッドが嫌われる • ?でエラー発生時のearly returnが簡単に書ける • エラー処理もサクサク書けるので エラーでハングアップとか起こしにくい • タイムアウトとかサボりがちですよね… let result = swd_transfer_inner_with_retry(config, swdio, swd_request, 0)?; write_u32(response, result); *response_count += 1;
  14. 実装してみて感じたRustの便利なところ 2021/7/15 Rust CMSIS-DAP で を実装してみた •結局のところ、 • 現代的な仕様の言語 •

    組込みで使える要求コストの低さ • GCなし、ゼロコスト抽象化、etc... というところが便利 (ライフタイムのチェックとかの安全性は言わずもがな)
  15. 余談:Arm以外のマイコンはどうなの? 2021/7/15 Rust CMSIS-DAP で を実装してみた • RISC-V • Tier2サポート

    • ESP32 • XtensaバックエンドのLLVMメインストリームへのマージ停滞中 • ISAリファレンスが無い問題は解消 • Espressifがドキュメントを用意 • 2021/6以降動きが無 • LLVMにマージされたらRustもあるいは? • 現状は自前でrustcビルドが必要