$30 off During Our Annual Pro Sale. View Details »

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

Kenta IDA
July 15, 2021
640

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

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

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

Kenta IDA

July 15, 2021
Tweet

Transcript

  1. RustでCMSIS-DAPを実装してみた
    NATURE BATH VOL.13 2021/07/15
    Kenta Ida (@ciniml)

    View Slide

  2. 自己紹介
    •井田 健太 (@ciniml)
    •仕事:FPGAの論理設計
    •使用言語:C++, SystemVerilog, Rust, C#
    •組込みRust本の1割くらい書きました
    (サンプルアプリ作ったり、デバッガ試したり)→
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた

    View Slide

  3. Rust CMSIS-DAP
    で を実装してみた
    というわけで、デバッガの話をします
    2021/7/15

    View Slide

  4. Wio Terminalとは?
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    • 組込みRust本でターゲットとしたマイコン・モジュール
    • 液晶、ボタン、スピーカーが筐体に収まっている
    • メインCPUはArmコア
    • ATSAMD51P19A (Microchip)
    • Cortex-M4F@120MHz
    • 無線通信機能 (WiFi, BLE) もついてる
    • バッテリは含まず
    • LiPoの処分に困るので助かる

    View Slide

  5. 組込みソフトウェアのデバッグ
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •MCUにはデバッグのための機能が組み込まれている
    • e.g. Armの場合:CoreSight DAP
    •JTAGやSWDといったプロトコルでデバッガと接続

    View Slide

  6. 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

    View Slide

  7. 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

    View Slide

  8. デバッグ用アダプタを作る
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •USBついてるMCUがあれば作れる
    •今回は
    Seeeduino XIAOを使用
    • ATSAMD21G18
    • USB2.0 FS
    •ファームは既存のもの
    • Seeedが移植している
    (のを改造したやつ) CMSIS-DAPファームウェア入り
    Seeeduino XIAO
    ホストPCの
    USBポートへ

    View Slide

  9. 既存CMSIS-DAPファームウェアの欠点
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •Windowsへのインストールがメンドイ!
    • ベンダ固有クラスなのでドライバが必要
    • Zadigを使ってドライバを導入する必要がある
    •挿しただけで動くようにしたい!
    • Zadigの手順書くのメンドイねん
    →WCIDの設定をしよう!

    View Slide

  10. 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非対応

    View Slide

  11. RustでCMSIS-DAPを実装する
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •そもそも可能なのか?
    • Seeeduino XIAOのコードをRustで書けるか? →書ける
    • xiao_m0クレートを使えばいい
    • USBを扱うクレートはあるのか? →ある
    • usb-deviceクレート
    • xiao_m0クレートがusb-deviceクレート内のトレイトを実装している
    →実装しよう!

    View Slide

  12. 開発中の風景
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    デバッガのデバッグ用XIAO
    Rust実装版ファームのXIAO
    Seeeduino XIAO用
    ベースボード
    実験用デバッグ対象の
    WioTerminal

    View Slide

  13. 開発の流れ
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •USBデバイスとしての機能を実装していく
    • usb_deviceクレートのUsbClassトレイトを実装するだけ
    • コンフィグレーション・ディスクリプタを返す
    • ストリング・ディスクリプタを返す
    • etc...
    •USBデバイス開発としてはかなり楽
    impl UsbClass for
    CmsisDapInterface <‘_, B> {
    fn get_configuration_descriptors(...) {...}
    fn get_bos_descriptors(...) {...}
    fn get_string(...) {...}
    fn control_in(...) {...}
    ...
    }

    View Slide

  14. 動作確認
    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 core::convert::From for
    embedded_graphics::pixelcolor::rgb_color::Rgb565>::from+64>
    xPSR 0x41000000 1090519040
    ...

    View Slide

  15. 動作確認 (Windows)
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •WCID対応→OK
    • WINUSBと互換性アリ
    •実際にWinUSBドライバが
    ロードされている
    Rust実装版CMSIS-DAP
    =WCID対応

    View Slide

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

    View Slide

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

    View Slide

  18. 実装してみて感じたRustの便利なところ
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •結局のところ、
    • 現代的な仕様の言語
    • 組込みで使える要求コストの低さ
    • GCなし、ゼロコスト抽象化、etc...
    というところが便利
    (ライフタイムのチェックとかの安全性は言わずもがな)

    View Slide

  19. まとめ
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    •とりあえずCMSIS-DAPうごいた
    •Rustがいろいろ便利なのでサクサク開発できた
    • cargo便利
    • usb_deviceクレート便利

    View Slide

  20. 余談:Arm以外のマイコンはどうなの?
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた
    • RISC-V
    • Tier2サポート
    • ESP32
    • XtensaバックエンドのLLVMメインストリームへのマージ停滞中
    • ISAリファレンスが無い問題は解消
    • Espressifがドキュメントを用意
    • 2021/6以降動きが無
    • LLVMにマージされたらRustもあるいは?
    • 現状は自前でrustcビルドが必要

    View Slide

  21. おしまい
    2021/7/15
    Rust CMSIS-DAP
    で を実装してみた

    View Slide