動機
ネットにある情報は2年前の情報でOS(jessie)やカーネルも古く(4.4など)、新しい情報もなかった。
今のOS(stretch)とカーネル(4.19.56)で試した結果無事成功したので、バージョンが・・・で二の足を踏んでいる人の後押しになりたかった。
対象
- 新しいOSとカーネルでラズパイをHID化しマウス・キーボードの操作をしたいと目論んでいる人。
省いている説明
- USB OTGでのラズパイのセットアップ
- gitなど各ツールの細かい使い方
検証環境
-
ラズパイ
- OS: strech
pi@pizerowh:dev$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 9.9 (stretch) Release: 9.9 Codename: stretch
- Kernel: 4.19.56
pi@pizerowh:~$ uname -a Linux pizerowh 4.19.56+ #1242 Wed Jun 26 17:24:44 BST 2019 armv6l GNU/Linux
手順
-
以下のページを参考にセットアップを進める
-
必要に応じてapt update & upgrade
-
HID化
-
セットアップ時にセットした下記の設定を削除し、USB経由でのインターネット接続の設定を削除する。
// cmdline.txtから以下を削除。 modules-load=dwc2,g_ether // これをしないと、デバイスは作成できても // 他の端末につないでも認識されない&コマンドを送った時にコマンドがハングする。
-
再起動
-
source/home/pi/enableHid.shもしくはhid.shを実行。エラーなく終了すればOK。
-
/dev以下にhidg0が存在することを確認。
pi@pizerowh:dev$ ls -l hidg0 crw------- 1 root root 240, 0 6月 28 09:44 hidg0 ※ カーネルバージョンを4.19.56にしてもデバイスが生えた事を確認。
-
他の端末にUSBで接続しUSBデバイスとして認識している事を確認。自分の場合は別のラズパイに接続しlsusbで確認した。lsusbで表示されるのはhid.sh内の下記名称が表示される。
echo 0x0104 > idProduct # Multifunction Composite Gadget <- このコメントの文字。
- 後は、zeroから/dev/hidg0に向けてコマンドを送り、他の端末のテキストエディタやターミナルに文字が表示されればOK。
マルチファンクション化
- 1USBに複数の機能をもたせるための設定を行うことも可能。
- 複合機の接続は1本のケーブルだけど、コピーとスキャナなど複数の機能を提供しているとかのイメージ。
- やり方としては、複数のFunctionとReportDescriptorをセットすることで可能。
手順
- キーボードもしくはマウスのどちらかの設定をベースに両方のファンクションを合わせる。
#!/bin/bash
# Snippet from https://github.com/girst/hardpass-sendHID/blob/master/README.md . In which, the following notice was left:
# this is a stripped down version of https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets - I don't claim any rights
modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "deadbeef01234567890" > strings/0x409/serialnumber
echo "blabla inc." > strings/0x409/manufacturer
echo "Generic USB mouse and Keyboard" > strings/0x409/product
# For Mouse
N="usb0"
mkdir -p functions/hid.$N
echo 2 > functions/hid.$N/protocol
echo 1 > functions/hid.$N/subclass
echo 8 > functions/hid.$N/report_length
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 > functions/hid.$N/report_desc
# For Keyboard
NN="usb1"
mkdir -p functions/hid.$NN
echo 1 > functions/hid.$NN/protocol
echo 1 > functions/hid.$NN/subclass
echo 8 > functions/hid.$NN/report_length
echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 >> functions/hid.$NN/report_desc
C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower
ln -s functions/hid.$N configs/c.$C/
ln -s functions/hid.$NN configs/c.$C/
ls /sys/class/udc > UDC
- 作成したshellを実行すると以下の設定になる。接続された側のlsusbで確認するとInterface Descriptorが2つ存在している。
pi@raspberrypi1:~ $ lsusb
Bus 001 Device 030: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
pi@raspberrypi1:~ $ lsusb -s001:030 -v
Bus 001 Device 030: ID 1d6b:0104 Linux Foundation Multifunction Composite Gadget
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1d6b Linux Foundation
idProduct 0x0104 Multifunction Composite Gadget
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 73
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 4
bmAttributes 0x80
(Bus Powered)
MaxPower 250mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 5
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 50
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 7
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 63
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 4
pi@raspberrypi1:~ $
参考リンク
- セットアップ後のHID化時のhid.shでハマった時に発見した情報。
- https://github.com/aidantwoods/RPi0w-keyboard/issues/1#issuecomment-309244795
- ベースとなるコードはこのリポジトリを元にしています。
- https://github.com/aidantwoods/RPi0w-keyboard