Skip to content

Instantly share code, notes, and snippets.

@rmed rmed/configfs_test.sh
Last active Jun 15, 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

commented Jul 8, 2018

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

@zbeekman

This comment has been minimized.

Copy link

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

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

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

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

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?

@seffyroff

This comment has been minimized.

Copy link

commented May 26, 2019

I'm not having any luck getting this going. I have Stretch Lite 2018-06-27 flashed on my Pi0W. The configfs_test.sh and tester.sh scripts in the right place, and it seems like the initialization works, looking at dmesg. tester.sh hangs forever however :/

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.