-
-
Save rmed/0d11b7225b3b772bb0dd89108ee93df0 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
sleep 15 | |
# Create gadget | |
mkdir /sys/kernel/config/usb_gadget/mykeyboard | |
cd /sys/kernel/config/usb_gadget/mykeyboard | |
# Add basic information | |
echo 0x0100 > bcdDevice # Version 1.0.0 | |
echo 0x0200 > bcdUSB # USB 2.0 | |
echo 0x00 > bDeviceClass | |
echo 0x00 > bDeviceProtocol | |
echo 0x00 > bDeviceSubClass | |
echo 0x08 > bMaxPacketSize0 | |
echo 0x0104 > idProduct # Multifunction Composite Gadget | |
echo 0x1d6b > idVendor # Linux Foundation | |
# Create English locale | |
mkdir strings/0x409 | |
echo "My manufacturer" > strings/0x409/manufacturer | |
echo "My virtual keyboard" > strings/0x409/product | |
echo "0123456789" > strings/0x409/serialnumber | |
# Create HID function | |
mkdir functions/hid.usb0 | |
echo 1 > functions/hid.usb0/protocol | |
echo 8 > functions/hid.usb0/report_length # 8-byte reports | |
echo 1 > functions/hid.usb0/subclass | |
# Write report descriptor | |
echo "05010906a101050719e029e71500250175019508810275089501810175019503050819012903910275019505910175089506150026ff00050719002aff008100c0" | xxd -r -ps > functions/hid.usb0/report_desc | |
# Create configuration | |
mkdir configs/c.1 | |
mkdir configs/c.1/strings/0x409 | |
echo 0x80 > configs/c.1/bmAttributes | |
echo 200 > configs/c.1/MaxPower # 200 mA | |
echo "Example configuration" > configs/c.1/strings/0x409/configuration | |
# Link HID function to configuration | |
ln -s functions/hid.usb0 configs/c.1 | |
# Enable gadget | |
ls /sys/class/udc > UDC | |
sleep 15 | |
/usr/local/bin/tester.sh & | |
# /usr/local/bin/tester.py & |
#!/usr/bin/env python3 | |
# | |
# Python file to test the gadget by writing "Hello World!" | |
# If used with the configfs_test.sh, place this file under /usr/local/bin/tester.py | |
# and uncomment the appropriate line | |
NULL_CHAR = chr(0) | |
def write_report(report): | |
with open('/dev/hidg0', 'rb+') as fd: | |
fd.write(report.encode()) | |
# H (press shift and H) | |
write_report(chr(32)+NULL_CHAR+chr(11)+NULL_CHAR*5) | |
# e | |
write_report(NULL_CHAR*2+chr(8)+NULL_CHAR*5) | |
# ll | |
write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
write_report(NULL_CHAR*8) | |
write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
# o | |
write_report(NULL_CHAR*2+chr(18)+NULL_CHAR*5) | |
# SPACE | |
write_report(NULL_CHAR*2+chr(44)+NULL_CHAR*5) | |
# W (press shift and W) | |
write_report(chr(32)+NULL_CHAR+chr(26)+NULL_CHAR*5) | |
# o | |
write_report(NULL_CHAR*2+chr(18)+NULL_CHAR*5) | |
# r | |
write_report(NULL_CHAR*2+chr(21)+NULL_CHAR*5) | |
# l | |
write_report(NULL_CHAR*2+chr(15)+NULL_CHAR*5) | |
# d | |
write_report(NULL_CHAR*2+chr(7)+NULL_CHAR*5) | |
# ! (press shift and 1) | |
write_report(chr(32)+NULL_CHAR+chr(30)+NULL_CHAR*5) | |
# Release all keys | |
write_report(NULL_CHAR*8) |
#!/bin/bash | |
# | |
# Bash file to test the gadget by writing "Hello World!" | |
# If used with the configfs_test.sh, place this file under /usr/local/bin/tester.sh | |
# and uncomment the appropriate line | |
function write_report { | |
echo -ne $1 > /dev/hidg0 | |
} | |
# H (press shift and H) | |
write_report "\x20\0\xb\0\0\0\0\0" | |
# e | |
write_report "\0\0\x8\0\0\0\0\0" | |
# ll | |
write_report "\0\0\xf\0\0\0\0\0" | |
write_report "\0\0\0\0\0\0\0\0" | |
write_report "\0\0\xf\0\0\0\0\0" | |
# o | |
write_report "\0\0\x12\0\0\0\0\0" | |
# SPACE | |
write_report "\0\0\x2c\0\0\0\0\0" | |
# W (press shift and W) | |
write_report "\x20\0\x1a\0\0\0\0\0" | |
# o | |
write_report "\0\0\x12\0\0\0\0\0" | |
# r | |
write_report "\0\0\x21\0\0\0\0\0" | |
# l | |
write_report "\0\0\xf\0\0\0\0\0" | |
# d | |
write_report "\0\0\x7\0\0\0\0\0" | |
# ! (press shift and 1) | |
write_report "\x20\0\x1e\0\0\0\0\0" | |
# Release al keys | |
write_report "\0\0\0\0\0\0\0\0" |
not sure if this is my case only
tester.sh - line 34 ~ 35
# r
write_report "\0\0\x21\0\0\0\0\0"
this report typed "4" instead of "r"
so I changed that 21 to 15 and works fine for me
(Reference: https://usb.org/sites/default/files/hut1_21.pdf Chaprter 10)
Hello @rmed, thanks for the blog post, it's the most clearer about HID with RPi Zero that I ever saw.
@flash76 Seems like the device already exists when you try to execute the script. Is there any gadget preconfigured in the RPi (e.g. ethernet over USB)?
Related to this, I'm trying to use a RPi Zero (not the W), but to have access to the terminal, I need to use the data micro USB, and I'm having the same problem that @flash76 had about the resource being busy, do you have any way that I could make it happen?
I don't know if this is related. I added "chown pi /dev/hidg0" at the end of the startup script so that the device is available to the regular user "pi".
Hello @rmed, thanks for the blog post, it's the most clearer about HID with RPi Zero that I ever saw.
Related to this, I'm trying to use a RPi Zero (not the W), but to have access to the terminal, I need to use the data micro USB, and I'm having the same problem that @flash76 had about the resource being busy, do you have any way that I could make it happen?