Help us understand the problem. What is going on with this article?

ラズパイ ZERO WH(stretch)のHID化

More than 1 year has passed since last update.

動機

ネットにある情報は2年前の情報でOS(jessie)やカーネルも古く(4.4など)、新しい情報もなかった。
今のOS(stretch)とカーネル(4.19.56)で試した結果無事成功したので、バージョンが・・・で二の足を踏んでいる人の後押しになりたかった。

対象

  • 新しいOSとカーネルでラズパイをHID化しマウス・キーボードの操作をしたいと目論んでいる人。

省いている説明

  1. USB OTGでのラズパイのセットアップ
  2. 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
    // これをしないと、デバイスは作成できても
    // 他の端末につないでも認識されない&コマンドを送った時にコマンドがハングする。
    
    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:~ $

参考リンク

hondasports8
物づくり(プログラミング)は好きみたいで、ちまちまプログラムを書いています。自分の頭の整理も兼ねてまとめておいた方がいいと思うネタについて残しておこうと思います。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away