ciniml / rust-dap

CMSIS-DAP Rust implementation
Apache License 2.0
86 stars 10 forks source link

rust-dapのサンプル実装を整理する #2

Closed ciniml closed 2 years ago

ciniml commented 2 years ago
  1. サンプル実装のディレクトリ構成を変更する (e.g. examples に移動するなど)
  2. サンプル実装のうち、他のプラットフォームでも共通で使いそうな部分を切り出す

現状の問題点としては、SwdIo traitの実装がプラットフォームごとに必要になっているが、実際のところはGPIO操作するところ以外の SWD のプロトコル共通の部分もかなりプラットフォーム依存側に含まれてしまっている。

https://github.com/ciniml/rust-dap/blob/main/rust-dap-xiao/src/main.rs#L135

これは、SwdIo インターフェースの実装として将来的にハードウェア機能を使えるように、ある程度抽象度高めに作っているからだが、現状はGPIOの直接操作部分との間がかなり存在している。

この部分を適切に切り出して、移植側では最低限のGPIOの上げ下げや周波数設定程度の操作で動かせるようにするように、もう一段階中間レイヤを挟む。

ciniml commented 2 years ago

Seeeduino XIAOにこだわる理由がXIAO RP2040が出た以上特に無いので、さっさとRP2040にも対応できるようにする。

XIAO (SAMD21) とXIAO RP2040の両方を並行して整理していけば、異なるMCU間でのちょうどよい抽象化層の検討もつくだろう。たぶん…

ciniml commented 2 years ago

rp-halにはXIAO RP2040のBSPはまだないが、とりあえずRPi Pico向けで動くと思うので、まずは rp-pico クレートを使ってRP2040実装をしてみる。

ciniml commented 2 years ago

USBシリアルのサンプルあるので、これベースにすればDAPの実装はすぐできるとおもわれる。PIOつかってゴニョゴニョとかはそのうちやろう。 https://github.com/rp-rs/rp-hal/blob/main/boards/rp-pico/examples/pico_usb_serial_interrupt.rs

ciniml commented 2 years ago

とりあえずXIAO (SAMD21) と XIAO RP2040版を boards ディレクトリ以下に入れるようにして、GPIOでBitBangする処理の共通部分を切り出すなどした。

https://github.com/ciniml/rust-dap/tree/2-refactor-examples/boards

SAMD21版はSWD接続できるのを確認できたが、RP2040版はまだ接続できない。 現状手元にロジアナがなくて波形観測できないので、帰ったら試すことにしよう。

ciniml commented 2 years ago

未初期化のポートの出力が有効になっていたらしく、そのピンがターゲットのリセットにつながっていたので、ターゲットがリセット状態になっていただけだった。(SWD的には正しく動いていた)

というわけで、RP2040版も動いた。

elfmimi commented 2 years ago

RP2040版をなんとか動かせました。 LinuxからUSBデバイスとして認識されなかったり、 UARTインターフェースを無しにしてやらないとWindowsでデバイスマネージャーに表示されるもののCMSIS-DAPのデバイスのハンドルを取得できない謎の挙動がありました。 UARTありの時にBOS/WCID周りを修正してCMSIS-DAPのインターフェースにWinUSBドライバを割り当てるというのは上手く出来たんですが。

ciniml commented 2 years ago

ウチの環境だとLinuxで特に問題なく認識してるんですけどなんでだろう… dmesgで何かエラーとか出てる感じですかね?

あとそういやまだLinuxでしか試してなかったですね…

ciniml commented 2 years ago

特に現状リポジトリに置いてるコードから変更なしで、Windowsで認識しましたね。何か違うんですかね… Windows11にしたせいか、デバイスのドライバ削除ができないので、こちらの環境はあまりクリーンではないかもしれませんが。

image
ciniml commented 2 years ago

RP2040向けのUART実装を始めたが、どうもUART割り込み周りの実装は rp-hal 0.3.0ではまだ入っておらず、mainブランチを使う必要がありそう。

https://github.com/rp-rs/rp-hal/blob/main/rp2040-hal/src/uart/reader.rs

elfmimi commented 2 years ago

また、お邪魔します。 Linux については再度検証したところ動くことを確認出来ました。 今度は Xiao_m0 の方も使って Windows 10 環境で挙動を調べましたが、RP2040 の場合と同様に認識されるものの使えません。認識の様子は、上で挙げて下さったデバイスマネージャの画像と同じです。シリアルポートのエコーバックは動きます。 これと似た現象は見たことがないのでじっくり調べるつもりです。

ヒント1: "USB Composite Device" の部分に WinUSB ドライバを強制的に(オレオレAuthenticodeによって)割り当てると ソフトウェアから使えるようになることが分かりました。ソフトウェアは openocd 、pyocd 、rusb で実装した自作テストプログラムです。

ヒント2: DAP-Link を改造して CMSIS-DAP の bulk インターフェース と シリアルポート だけにすると同様に認識するのに使えないものになりました。Linux では使えます。デバイスの根幹に WinUSB ドライバを割り当てると使えます。

素直に考えると WebUSB ( WinUSB ではなく WebUSB ) のインターフェースを定義しておくことがうまく動くために必要、 となりますが、はたして?

他の Windows 環境 、Windows 11 の環境などでも試してみたいと思います。

ciniml commented 2 years ago

なるほど。そういえばComposite DeviceにしてからWindowsで動くの確認したか怪しいですね。確認しておきます。

…なんかそういやlibusbでのデバイス列挙時の見え方が変わってて、OpenOCDで見つけてくれなかったので、なんかOpenOCD側いじったような気がしてきた。

いずれにせよ、そもそも rust-dap 実装したの、Windowsでzadig無しでドライバが入るDAPLink実装が欲しかったからなので、対応しようと思います。

ciniml commented 2 years ago

UARTの実装が難航中。共有リソースの効率的な管理が面倒になってきたので、RTICを使うことにする。

ciniml commented 2 years ago

割り込みタイミングとか見ている限り、RX FIFOが半分以上たまった状態で漸く UART0_IRQ が起きていた。 原因はuartのインスタンスのロックをUSB_IRQ内でusb_serialの送信バッファ分を送り終わるまで取ったままだったため。

UARTもreader/writerにsplitできるので、splitしたうえでそれぞれ個別にロックを取るように修正して、ループバックが動くようになった。

ciniml commented 2 years ago

一旦欲しい機能はRP2040版に実装できたのでmergeする。 https://github.com/ciniml/rust-dap/pull/6

ciniml commented 2 years ago

忘れないうちに波形のログだけ貼っておく

image

波形を見る限り、 UARTのデータが半分以上貯まった時 (図だと24個目の受信中) に割り込みが起きているのが分かる。 (パケット図の23に現在位置マークがついている)

image image

また、送受信処理中は基本的に USBCTRL_IRQ の中で処理が実行されている。これは送信処理自体を割り込み処理中に実行しているからである。

ciniml commented 2 years ago

USB処理周りに悪影響が出てきた場合は、UART送信処理をUSB IRQから追い出してメインループ内でやるようにしたほうがよい。