Raspberry Pi PicoのUSBポートは、BootROMの機能によるファームウェア書き込みに使われる他、Pico SDKではMSC他いくつかのデバイスクラスで動作したり、microPythonではシリアルコンソールとして使われたりしています。
今回、NuttX for Raspberry Pi PicoでもようやくUSBが使えるようになりました。
現在、
- CDC/ACM (Communication Device Class Abstract Control Model - シリアルポート)
- MSC (Mass Storage Class - マスストレージ)
- CDC/ACM と MSC のコンポジットデバイス
の3種類のデバイスクラスでの動作を確認しています。
RP2040のUSBデバイスコントローラ
Raspberry Pi PicoのSoCであるRP2040は、USB フルスピード(12Mbps)のホスト/デバイス両対応のコントローラを持っています。
このコントローラはどうやらRP2040の独自IPのようなのですが、Pico SDKなどは TinyUSB というオープンソースの組み込みシステム向けUSBスタックを利用して、この中にRP2040対応を取り込んで使っています。
NuttXはTinyUSBとは異なる独自のUSBスタックを持っているので、RP2040 DatasheetのUSBコントローラに関する記述やTinyUSBのRP2040対応実装を参考に、USBデバイスコントローラのドライバを実装しました。
NuttX コンフィグレーション
USBのサポートに伴い、新たに以下のコンフィグレーションが追加されています。
-
raspberrypi-pico:usbnsh
- 最小構成の
raspberrypi-pico:nsh
の、UARTシリアルコンソールの代わりにUSB CDC/ACMをコンソールデバイスとして使用します - これまでRaspberry Pi PicoでNuttXを使うには、UARTコンソールをPCなどに繋ぐために別途USB - シリアル変換基板が必要でしたが、このコンフィグレーションで変換基板なしでの利用も可能になりました
- 最小構成の
-
raspberrypi-pico:usbmsc
- USB MSCとCDC/ACMを利用可能にしたコンフィグレーションです
- コンソールには従来通りUARTシリアルコンソールを使用します。MSCのストレージには、SPIで接続したmicroSDカードを使用します。接続は以前の記事「NuttX for Raspberry Pi PicoでmicroSDカードを読み書き (SPI接続)」と同じです
- NuttX起動時にはUSBデバイスはまだ有効になっていません。MSCとCDC/ACMはそれぞれ、NuttShellの以下のコマンドで接続を制御できます
-
msconn
/msdis
(MSCの接続、解除) -
sercon
/serdis
(CDC/ACMの接続、解除)
-
-
raspberrypi-pico:composite
-
usbmsc
は MSC と CDC/ACM のどちらかの排他利用ですが、このコンフィグレーションはこれら両方の複合(コンポジット)デバイスを提供します - 起動後、NuttShellの以下のコマンドで接続を制御できます。
-
conn
/disconn
(MSC+CDC/ACMの接続、解除)
-
-
更に、これまでUARTコンソールを使っていた raspberrypi-pico:displaypack
もCDC/ACMコンソールに変更することで、Pico Display Packを直接Raspberry Pi Picoに挿しても使えるようになりました。
(参考: NuttX for Raspberry Pi PicoでPico Display Packを使う)
ビルドと起動
ビルドの方法は通常通りです。raspberrypi-pico:usbnsh
をビルドしてみます。
$ git clone https://github.com/apache/incubator-nuttx.git nuttx
$ git clone https://github.com/apache/incubator-nuttx-apps.git apps
$ cd nuttx
$ ./tools/configure.sh raspberrypi-pico:usbnsh
$ make
以下のように、USBコンソールで使えるようになりました。
Pico Display Pack や Tiny2040 も USBコンソールで使ってみます。
未サポートの機能
- 他のデバイスクラス
- Pico SDK (Tiny USB) ではUSB AudioやHID、MIDIなども使えるのですが、NuttXにはまだこれらのクラスドライバの実装がないようです
- USBホストサポート
- RP2040のUSBコントローラにはUSBホスト機能もあってTiny USBでも利用可能ですが、NuttXではまだサポートしていません。Raspberry Pi PicoをUSBホストとして使うにはOTGケーブルが必要な他、Pico自身の電源を別途供給する必要もあってUSBデバイスより若干面倒だったりします
- USB MSCのRP2040ワークアラウンド
-
具体的には、MSCの内部で使われるSCSIプロトコルのやり取りで、USBホストから未サポートのフラグが指定された場合やホストの要求するデータ長より短いデータを返す場合などに、本来の実装では一旦エンドポイントをストールさせることでホストにエラーを通知するのですが、RP2040の場合だけストール状態に入れず単に無視するようにしています (TinyUSBのMSCクラスドライバもストールに入らずこのような動作をしているため、それに合わせた)。 ↩
-
データシートにあまり記述がなくてエンドポイントの正しいストールへの入り方/出方がよく分からないのと、既存の実装であるTinyUSBもストールに入ることがないので参考にすることができず、なかなか難しいです…。 ↩