あまり需要ないかも知れませんが、下記の「Arduinoで作成したUSB接続のPC音量調整ボタン」のRaspberry Piバージョンを作成したので、その手順と説明メモになります。
Raspberry PiをUSB機器(ガジェット)にするざっくりとした説明
通常、Raspberry Pi のUSB端子には、マウスやキーボードといったRaspberry Piで使う周辺機器を接続するのですが、Raspberry Pi Zeroは、PCとUSBケーブルで接続して、自分自身をPCのUSB機器(ガジェット)にすることができます。
USBにはOTGという、PC無しでUSB機器どうしを接続させる規格があって、それを使うとUSBの親になったり、子なったりできます。
そして、LinuxにはUSB OTGドライバーが入っているので、今回それを用いてRaspberry PiをUSBの子機として動作させることにより、Raspberry PiをUSBガジェットにしています。
しかし残念なことに、全てのRaspberry PiがUSBガジェットになれるかというとそうではなく、下記記事によると、ハードウェアの仕様により、他のRaspberry PiはUSBガジェットにはできないようです。
ドライバーを使ってUSBガジェットをフルスクラッチするとなると気が遠くなりそうですが、幸い、Linuxには、いくつかの設定を行うだけでお手軽にUSBガジェットが作成できる「Composite USB Gadgets」という、 USB OTGのラッパーフレームワークが入っているので、今回はそれを用いて、USBガジェット、つまり、PC音量調整するUSB HIDを作成しました。
手順
USB OTGドライバとComposite USB Gadgetsの読み込み
「/boot/config.txt」に下記を追記します
dtoverlay=dwc2
「/etc/modules」に下記を追記します
dwc2 libcomposite
「 dwc2」がUSB OTGドライバー、「libcomposite」がComposite USB Gadgetsで、それらがRaspberry Pi起動時に読み込まれるようになります。
Raspberry Piを再起動します。
Raspberry Piが立ち上がると、既にComposite USB Gadgetsが動作しているので、続いてUSBガジェットを作成します。
USBガジェットの作成
下記シェルスクリプトをsudo
で実行します。
usb_volume_button.sh
#!/bin/bash CONFIGS_HOME=/sys/kernel/config GADGET_NAME=g1 NAME=c NUMBER=1 FUNC_NAME=hid INSTANCE_NAME=usb0 BASE=${CONFIGS_HOME}/usb_gadget/${GADGET_NAME} mkdir -p ${BASE}/ cd ${BASE}/ echo 0x1d6b > idVendor echo 0x0104 > idProduct mkdir -p ${BASE}/configs/${NAME}.${NUMBER}/ mkdir -p ${BASE}/functions/${FUNC_NAME}.${INSTANCE_NAME}/ cd ${BASE}/functions/${FUNC_NAME}.${INSTANCE_NAME}/ echo 0 > protocol echo 0 > subclass echo 1 > report_length echo -ne \\x05\\x0c\\x09\\x01\\xa1\\x01\\x15\\x00\\x25\\x01\\x09\\xe9\\x09\\xea\\x09\\xe2\\x75\\x01\\x95\\x03\\x81\\x02\\x75\\x01\\x95\\x05\\x81\\x03\\xc0 > report_desc cd ${BASE}/ ln -s functions/${FUNC_NAME}.${INSTANCE_NAME} configs/${NAME}.${NUMBER} ls /sys/class/udc > UDC
ディスクリプタはArduinoで作成した時と同じです。ただし、ReportIDはComposite USB Gadgetsの方で決まっているようで、指定すると動作しなかったのでここでは外しました。
シェルスクリプトを実行すると、Raspberry Piが音量調整コントローラーのUSBガジェットになります。
Raspberry PiをPCにつなぐと、デバイスマネージャーの[ヒューマンインターフェイスデバイス]-[HID準拠コンシューマ制御デバイス]に現れます。
「HID準拠コンシューマ制御デバイス」は複数あったりするんですが、[プロパティ]-[詳細]-[ハードウェアID]を見て、上記シェルスクリプトで設定したベンダーIDが「1D6B」、プロダクトIDが「0104」となっているものが、Raspberry Piです。
音量調整信号の送信
USBガジェットが作成されると、「/dev/hidg0」というファイルが作成されるので、このファイルを介して、PCとデータの送受信を行います。
音量調整信号は下位ビットから「音量UP→音量DOWN→消音」の順で割り当てたので、送信のサンプルは下記のようになります。(sudoで実行します)
send_volume_control_signal.sh
#!/bin/bash echo -ne "\x1" > /dev/hidg0 # UP echo -ne "\0" > /dev/hidg0 # RELEASE echo -ne "\x2" > /dev/hidg0 # DOWN echo -ne "\0" > /dev/hidg0 # RELEASE echo -ne "\x4" > /dev/hidg0 # MUTE echo -ne "\0" > /dev/hidg0 # RELEASE
USBガジェットの削除
sudo echo "" > /sys/kernel/config/usb_gadget/g1/UDC
で作成したUSBガジェットが削除されます。
PCにつないだままUSBガジェットの作成・削除を行っても大丈夫です。
削除すると、PCからは、そのUSBガジェットが取り外されたように見えます。
応用
他のHIDを作成する際
- マウスの場合は「protocolを2、subclassを1」
- キーボードの場合は「protocolを1、subclassを1」
- その他の場合は「protocolを0、subclassを0」
に設定します。
通常HIDはPCのOSが立ち上がってから認識されるのですが、マウス・キーボードはこの設定により、PCのブート時にも認識されて使えるようになります。
Composite USB GadgetsはHID以外に、ストレージ・LAN・シリアルなどのUSBガジェットも作成できるので、暇があったら試してみたいですね。
Composite USB Gadgets ファンクション一覧
1. ACM function 2. ECM function 3. ECM subset function 4. EEM function 5. FFS function 6. HID function 7. LOOPBACK function 8. MASS STORAGE function 9. MIDI function 10. NCM function 11. OBEX function 12. PHONET function 13. RNDIS function 14. SERIAL function 15. SOURCESINK function 16. UAC1 function (legacy implementation) 17. UAC2 function 18. UVC function 19. PRINTER function 20. UAC1 function (new API)