Frederic98 / USBGadget

A python library for creating and interfacing with USB Gadgets on Linux through libcomposite
MIT License
10 stars 1 forks source link

Doesn't work on RaspberryPi 4 CM #2

Open jds1993cologne opened 1 year ago

jds1993cologne commented 1 year ago

Start command: sudo python3 test-gadget.py

Code: `import time import logging

import usb_gadget

logging.basicConfig(level=logging.DEBUG)

### # Step 1: Create USB gadget (probably needs root permissions) gadget = usb_gadget.USBGadget('test_gadget') gadget.idVendor = '0x1d6b' gadget.idProduct = '0x0104' gadget.bcdDevice = '0x0100' gadget.bcdUSB = '0x0200'

strings = gadget['strings']['0x409'] strings.serialnumber = '0123456789' strings.manufacturer = 'Test' strings.product = 'Test USB Gadget'

config = gadget['configs']['c.1'] config.bmAttributes = '0x80' config.MaxPower = '250' config['strings']['0x409'].configuration = 'Test Configuration'

function = usb_gadget.HIDFunction(gadget, 'keyboard0') descriptor = [ 0x05, 0x01, # Usage Page (Generic Desktop Ctrls) 0x09, 0x06, # Usage (Keyboard) 0xA1, 0x01, # Collection (Application) 0x05, 0x07, # Usage Page (Kbrd/Keypad) 0x19, 0xE0, # Usage Minimum (0xE0) 0x29, 0xE7, # Usage Maximum (0xE7) 0x15, 0x00, # Logical Minimum (0) 0x25, 0x01, # Logical Maximum (1) 0x75, 0x01, # Report Size (1) 0x95, 0x08, # Report Count (8) 0x81, 0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x01, # Report Count (1) 0x75, 0x08, # Report Size (8) 0x81, 0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x95, 0x06, # Report Count (6) 0x75, 0x08, # Report Size (8) 0x15, 0x00, # Logical Minimum (0) 0x25, 0x65, # Logical Maximum (101) 0x05, 0x07, # Usage Page (Kbrd/Keypad) 0x19, 0x00, # Usage Minimum (0x00) 0x29, 0x65, # Usage Maximum (0x65) 0x81, 0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, # End Collection ] function.protocol = '0' function.subclass = '0' function.report_length = '8' function.report_desc = bytes(descriptor) gadget.link(function, config)

gadget.activate()

### # Step 2: Use USB Gadget

# gadget = usb_gadget.USBGadget('test_gadget') # function = usb_gadget.HIDFunction(gadget, 'keyboard0') keyboard = usb_gadget.KeyboardGadget(function.device, 6) # Above, we defined a report count of 6

print('Typing in 5 seconds...') time.sleep(5) for letter in 'Hello, world': keyboard.press_and_release(letter)

### # Step 3: Destroy the gadget # When you want to remove the USB gadget, call gadget.destroy()

# gadget = usb_gadget.USBGadget('test_gadget') gadget.destroy() `

Output: `DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/idVendor = '0x1d6b' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/idProduct = '0x0104' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/bcdDevice = '0x0100' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/bcdUSB = '0x0200' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/strings/0x409/serialnumber = '0123456789' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/strings/0x409/manufacturer = 'Test' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/strings/0x409/product = 'Test USB Gadget' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/configs/c.1/bmAttributes = '0x80' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/configs/c.1/MaxPower = '250' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/configs/c.1/strings/0x409/configuration = 'Test Configuration' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/functions/hid.keyboard0/protocol = '0' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/functions/hid.keyboard0/subclass = '0' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/functions/hid.keyboard0/report_length = '8' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/functions/hid.keyboard0/report_desc = b'\x05\x01\t\x06\xa1\x01\x05\x07\x19\xe0)\xe7\x15\x00%\x01u\x01\x95\x08\x81\x02\x95\x01u\x08\x81\x03\x95\x06u\x08\x15\x00%e\x05\x07\x19\x00)e\x81\x00\xc0' DEBUG:usb_gadget:/sys/kernel/config/usb_gadget/test_gadget/UDC = 'fe980000.usb' OSError: [Errno 16] Device or resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/home/pi/test-gadget.py", line 58, in gadget.activate() File "/usr/local/lib/python3.9/dist-packages/usb_gadget/usb_gadget.py", line 101, in activate self.UDC = device File "/usr/local/lib/python3.9/dist-packages/usb_gadget/usb_gadget.py", line 76, in setattr f.write(value) OSError: [Errno 16] Device or resource busy `

lexelby commented 3 months ago

I got this error when something else had already registered a USB gadget. Do you have TinyPilot or pikvm installed, or the like? It seems like at least on the Pi 4, you can only have one gadget (with up to 4 functions) -- may be a general Linux limitation.

If something does have a gadget registered already, then you can mess with it using that_gadget = usb_gadget.USBGadget('that-gadget-name'). Just do that_gadget.deactivate(), add your function, link it in, and then do that_gadget.activate(), and your new function should work.