HID의 configfs, 비어 있음/sys/class/udc

HID의 configfs, 비어 있음/sys/class/udc

현재 마우스 장치용 USB HID를 구현하고 있습니다. 다른 컴퓨터에서 마우스 움직임을 시뮬레이션하기 위해 라즈베리 파이에서 예상한 대로 정확하게 작동합니다. 다음과 같은 것을 구현하십시오.이것. 세부 구현:

#!/usr/bin/env bash

# Configures USB gadgets per: https://www.kernel.org/doc/Documentation/usb/gadget_configfs.txt

# Exit on first error.
set -e

# Echo commands to stdout.
set -x

# Treat undefined environment variables as errors.
set -u

modprobe libcomposite

# Adapted from https://github.com/girst/hardpass-sendHID/blob/master/README.md

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

STRINGS_DIR="strings/0x409"
mkdir -p "$STRINGS_DIR"
echo "6b65796d696d6570690" > "${STRINGS_DIR}/serialnumber"
echo "tinypilot" > "${STRINGS_DIR}/manufacturer"
echo "Multifunction USB Device" > "${STRINGS_DIR}/product"

# Keyboard
KEYBOARD_FUNCTIONS_DIR="functions/hid.keyboard"
mkdir -p "$KEYBOARD_FUNCTIONS_DIR"
echo 1 > "${KEYBOARD_FUNCTIONS_DIR}/protocol" # Keyboard
echo 1 > "${KEYBOARD_FUNCTIONS_DIR}/subclass" # Boot interface subclass
echo 8 > "${KEYBOARD_FUNCTIONS_DIR}/report_length"
# Write the report descriptor
# Source: https://www.kernel.org/doc/html/latest/usb/gadget_hid.html
D=$(mktemp)
echo -ne \\x05\\x01 >> "$D" # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x06 >> "$D" # USAGE (Keyboard)
echo -ne \\xa1\\x01 >> "$D" # COLLECTION (Application)
echo -ne \\x05\\x07 >> "$D" #   USAGE_PAGE (Keyboard)
echo -ne \\x19\\xe0 >> "$D" #   USAGE_MINIMUM (Keyboard LeftControl)
echo -ne \\x29\\xe7 >> "$D" #   USAGE_MAXIMUM (Keyboard Right GUI)
echo -ne \\x15\\x00 >> "$D" #   LOGICAL_MINIMUM (0)
echo -ne \\x25\\x01 >> "$D" #   LOGICAL_MAXIMUM (1)
echo -ne \\x75\\x01 >> "$D" #   REPORT_SIZE (1)
echo -ne \\x95\\x08 >> "$D" #   REPORT_COUNT (8)
echo -ne \\x81\\x02 >> "$D" #   INPUT (Data,Var,Abs)
echo -ne \\x95\\x01 >> "$D" #   REPORT_COUNT (1)
echo -ne \\x75\\x08 >> "$D" #   REPORT_SIZE (8)
echo -ne \\x81\\x03 >> "$D" #   INPUT (Cnst,Var,Abs)
echo -ne \\x95\\x05 >> "$D" #   REPORT_COUNT (5)
echo -ne \\x75\\x01 >> "$D" #   REPORT_SIZE (1)
echo -ne \\x05\\x08 >> "$D" #   USAGE_PAGE (LEDs)
echo -ne \\x19\\x01 >> "$D" #   USAGE_MINIMUM (Num Lock)
echo -ne \\x29\\x05 >> "$D" #   USAGE_MAXIMUM (Kana)
echo -ne \\x91\\x02 >> "$D" #   OUTPUT (Data,Var,Abs)
echo -ne \\x95\\x01 >> "$D" #   REPORT_COUNT (1)
echo -ne \\x75\\x03 >> "$D" #   REPORT_SIZE (3)
echo -ne \\x91\\x03 >> "$D" #   OUTPUT (Cnst,Var,Abs)
echo -ne \\x95\\x06 >> "$D" #   REPORT_COUNT (6)
echo -ne \\x75\\x08 >> "$D" #   REPORT_SIZE (8)
echo -ne \\x15\\x00 >> "$D" #   LOGICAL_MINIMUM (0)
echo -ne \\x25\\x65 >> "$D" #   LOGICAL_MAXIMUM (101)
echo -ne \\x05\\x07 >> "$D" #   USAGE_PAGE (Keyboard)
echo -ne \\x19\\x00 >> "$D" #   USAGE_MINIMUM (Reserved)
echo -ne \\x29\\x65 >> "$D" #   USAGE_MAXIMUM (Keyboard Application)
echo -ne \\x81\\x00 >> "$D" #   INPUT (Data,Ary,Abs)
echo -ne \\xc0 >> "$D"      # END_COLLECTION
cp "$D" "${KEYBOARD_FUNCTIONS_DIR}/report_desc"

# Mouse
MOUSE_FUNCTIONS_DIR="functions/hid.mouse"
mkdir -p "$MOUSE_FUNCTIONS_DIR"
echo 0 > "${MOUSE_FUNCTIONS_DIR}/protocol"
echo 0 > "${MOUSE_FUNCTIONS_DIR}/subclass"
echo 5 > "${MOUSE_FUNCTIONS_DIR}/report_length"
# Write the report descriptor
D=$(mktemp)
echo -ne \\x05\\x01 >> "$D"      # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x02 >> "$D"      # USAGE (Mouse)
echo -ne \\xA1\\x01 >> "$D"      # COLLECTION (Application)
                                 #   8-buttons
echo -ne \\x05\\x09 >> "$D"      #   USAGE_PAGE (Button)
echo -ne \\x19\\x01 >> "$D"      #   USAGE_MINIMUM (Button 1)
echo -ne \\x29\\x08 >> "$D"      #   USAGE_MAXIMUM (Button 8)
echo -ne \\x15\\x00 >> "$D"      #   LOGICAL_MINIMUM (0)
echo -ne \\x25\\x01 >> "$D"      #   LOGICAL_MAXIMUM (1)
echo -ne \\x95\\x08 >> "$D"      #   REPORT_COUNT (8)
echo -ne \\x75\\x01 >> "$D"      #   REPORT_SIZE (1)
echo -ne \\x81\\x02 >> "$D"      #   INPUT (Data,Var,Abs)
                                 #   x,y absolute coordinates
echo -ne \\x05\\x01 >> "$D"      #   USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x30 >> "$D"      #   USAGE (X)
echo -ne \\x09\\x31 >> "$D"      #   USAGE (Y)
echo -ne \\x16\\x00\\x00 >> "$D" #   LOGICAL_MINIMUM (0)
echo -ne \\x26\\xFF\\x7F >> "$D" #   LOGICAL_MAXIMUM (32767)
echo -ne \\x75\\x10 >> "$D"      #   REPORT_SIZE (16)
echo -ne \\x95\\x02 >> "$D"      #   REPORT_COUNT (2)
echo -ne \\x81\\x02 >> "$D"      #   INPUT (Data,Var,Abs)
                                 #   vertical wheel
echo -ne \\x09\\x38 >> "$D"      #   USAGE (wheel)
echo -ne \\x15\\x81 >> "$D"      #   LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F >> "$D"      #   LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 >> "$D"      #   REPORT_SIZE (8)
echo -ne \\x95\\x01 >> "$D"      #   REPORT_COUNT (1)
echo -ne \\x81\\x06 >> "$D"      #   INPUT (Data,Var,Rel)
                                 #   horizontal wheel
echo -ne \\x05\\x0C >> "$D"      #   USAGE_PAGE (Consumer Devices)
echo -ne \\x0A\\x38\\x02 >> "$D" #   USAGE (AC Pan)
echo -ne \\x15\\x81 >> "$D"      #   LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F >> "$D"      #   LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 >> "$D"      #   REPORT_SIZE (8)
echo -ne \\x95\\x01 >> "$D"      #   REPORT_COUNT (1)
echo -ne \\x81\\x06 >> "$D"      #   INPUT (Data,Var,Rel)
echo -ne \\xC0 >> "$D"           # END_COLLECTION
cp "$D" "${MOUSE_FUNCTIONS_DIR}/report_desc"

CONFIG_INDEX=1
CONFIGS_DIR="configs/c.${CONFIG_INDEX}"
mkdir -p "$CONFIGS_DIR"
echo 250 > "${CONFIGS_DIR}/MaxPower"

CONFIGS_STRINGS_DIR="${CONFIGS_DIR}/strings/0x409"
mkdir -p "$CONFIGS_STRINGS_DIR"
echo "Config ${CONFIG_INDEX}: ECM network" > "${CONFIGS_STRINGS_DIR}/configuration"

ln -s "$KEYBOARD_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ln -s "$MOUSE_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ls /sys/class/udc > UDC

chmod 777 /dev/hidg0
chmod 777 /dev/hidg1

그러나 Linux를 실행하는 산업용 PC에서 구현하면 동일한 설정이 작동하지 않습니다. 주요 문제는 /sys/class/udc가 비어 있다는 것입니다. Raspi의 경우 udc fe980000.usb가 있습니다. 산업용 PC의 경우 이는 존재하지 않습니다. 다양한 다른 포럼에서. Raspberry Pi에는 dtoverlay = dwc2 구성이 드라이버와 관련되어 있기 때문에 이 기능이 있습니다. 산업용 컴퓨터에는 그런 드라이버가 없는 것 같습니다.

다음 사항이 조사/관찰되었습니다.

  1. configfs의 커널 구성 설정이 올바른지 확인하십시오. CONFIG_USB_CONFIGFS_F_HID=y

  2. modprobe configfs 및 libcomposite가 작동 중입니다.

  3. ls /dev에 hidg0 또는 hidg(번호)가 표시되지 않습니다.

  4. /sys/kernel/config/usb_gadget에 설치하면 폴더를 생성하여 예상대로 작동합니다.

유일한 문제/증상은 /dev/hidg0이 나타나지 않아 쓸 수 없다는 것입니다. 동시에 udc가 비어 있어 bash 스크립트가 ls /sys/class/udc > UDC에서 실패하게 됩니다.

산업용 컴퓨터의 경우 배포자 ID: Ubuntu 설명: Ubuntu 18.04.5 LTS 버전: 18.04 코드 이름: bionic 5.4.0-81-generic에서 실행됩니다.

나는 리눅스/우분투를 처음 접했기 때문에 미리 사과드립니다. 어떤 도움이라도 대단히 감사하겠습니다.

하드웨어 편집기: 아키텍처: x86_64 CPU 작동 모드: 32비트, 64비트 엔디안: Little Endian CPU: 16 온라인 CPU 목록: 각 스레드 0-15개 코어: 소켓당 코어 2개: 8 소켓: 1 NUMA 노드: 1 공급업체 ID : GenuineIntel CPU 제품군: 6 모델: 158 모델 이름: Intel(R) Core(TM) i9-9900T CPU @ 2.10GHz 단계: 13 CPU MHz: 899.790 CPU 최대 MHz: 4400,0000 CPU 최소 MHz: 800,0000 BogoMIPS: 4199.88 가상화: VT-x L1d 캐시: 32K L1i 캐시: 32K L2 캐시: 256K L3 캐시: 16384K NUMA 노드 0 CPU: 0-15

lsusb Bus002 Device002: ID 1058:25ee Western Digital Technologies, Inc. Bus002 Device001: ID 1d6b:0003 Linux Foundation 3.0 루트 허브 Bus001 Device002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 허브 Bus001 Device001: ID 1d6b:0002 Linux Foundation 2.0 루트 허브

Raspi에 비해 COM 포트와 USB 포트가 더 많습니다.

관련 정보