Skip to content

Instantly share code, notes, and snippets.

@rmed rmed/configfs_test.sh
Last active Mar 19, 2019

Embed
What would you like to do?
RPi Zero keyboard test
#!/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"
@rmed

This comment has been minimized.

Copy link
Owner Author

rmed commented Jul 8, 2018

Tested on Raspbian Stretch (lite) 2018-06-27.

@zbeekman

This comment has been minimized.

Copy link

zbeekman commented Aug 1, 2018

@rmed: Great blog post! (https://www.rmedgar.com/blog/using-rpi-zero-as-keyboard-setup-and-device-definition) Where is tester.sh or tester.py? I would like to get more information on setting up sending keystrokes via USB. I'm making a little password vault/manager gadget and it would be great to be able to send the password input over USB.

@rmed

This comment has been minimized.

Copy link
Owner Author

rmed commented Aug 1, 2018

@zbeekman: I updated the gist with the Python and Bash scripts I used to test the gadget config, they simply write Hello World! by emulating each keystroke. Hope this helps!

@flash76

This comment has been minimized.

Copy link

flash76 commented Dec 5, 2018

@rmed: Thanks for the tutorial, but I am having some problems. When I run configfs.sh. I get this:
./tempinstall.sh: line 29: echo: write error: Device or resource busy ./tempinstall.sh: line 30: echo: write error: Device or resource busy ./tempinstall.sh: line 31: echo: write error: Device or resource busy xxd: Device or resource busy ln: failed to create symbolic link 'configs/c.1/hid.usb0': File exists ls: write error: Device or resource busy

@rmed

This comment has been minimized.

Copy link
Owner Author

rmed commented Mar 16, 2019

@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)?

@Shamber

This comment has been minimized.

Copy link

Shamber commented Mar 19, 2019

Hi.
I have orange pi device and i want use keyboard gadget.
I setup it with this script and it work in gedit terminal and so on on my local machine/
But when i try it to connect to my macbook it doesn't work.
At first i think usb on my book doesn't work. But if i connect usb keyboard it perfectly work.
So how i can "clone" my existing keyboard with libcompose?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.