Multifunction Composite Gadget Driver



DWC3 is a SuperSpeed (SS) USB 3.0 Dual-Role-Device (DRD) from Synopsys. Main features of DWC3: The SuperSpeed USB controller features. The Multifunction Compasite Gadget have been cleaned up and refactored so hopefully it looks prettier and works at least as good as before changes.

1-.- org -.- 2 3. Overview 4 5 The Multifunction Composite Gadget (or gmulti) is a composite gadget 6 that makes extensive use of the composite framework to provide 7 a. Multifunction gadget. 8 9 In it's standard configuration it provides a single USB configuration 10 with RNDIS1 (that is Ethernet), USB CDC2 ACM (that is serial) and 11.

Overview¶

The Multifunction Composite Gadget (or g_multi) is a composite gadgetthat makes extensive use of the composite framework to providea… multifunction gadget.

In it’s standard configuration it provides a single USB configurationwith RNDIS[1] (that is Ethernet), USB CDC[2] ACM (that is serial) andUSB Mass Storage functions.

A CDC ECM (Ethernet) function may be turned on via a Kconfig optionand RNDIS can be turned off. If they are both enabled the gadget willhave two configurations – one with RNDIS and another with CDC ECM[3].

Please note that if you use non-standard configuration (that is enableCDC ECM) you may need to change vendor and/or product ID.

Host drivers¶

To make use of the gadget one needs to make it work on host side –without that there’s no hope of achieving anything with the gadget.As one might expect, things one need to do very from system to system.

Linux host drivers¶

Since the gadget uses standard composite framework and appears as suchto Linux host it does not need any additional drivers on Linux hostside. All the functions are handled by respective drivers developedfor them.

This is also true for two configuration set-up with RNDISconfiguration being the first one. Linux host will use the secondconfiguration with CDC ECM which should work better under Linux.

Windows host drivers¶

For the gadget to work under Windows two conditions have to be met:

Detecting as composite gadget¶

First of all, Windows need to detect the gadget as an USB compositegadget which on its own have some conditions[4]. If they are met,Windows lets USB Generic Parent Driver[5] handle the device which thentries to match drivers for each individual interface (sort of, don’tget into too many details).

The good news is: you do not have to worry about most of theconditions!

The only thing to worry is that the gadget has to have a singleconfiguration so a dual RNDIS and CDC ECM gadget won’t work unless youcreate a proper INF – and of course, if you do submit it!

Installing drivers for each function¶

The other, trickier thing is making Windows install drivers for eachindividual function.

Table of Contents.Download Realme USB Driver LatestIf you want to use the Realme USB Driver then first you have to download it. And so you will need the USB Driver in most of the cases.You May Also Like. Anydata usb mtp device driver download for windows 7.

For mass storage it is trivial since Windows detect it’s an interfaceimplementing USB Mass Storage class and selects appropriate driver.

Things are harder with RDNIS and CDC ACM.

RNDIS¶

Multifunction Composite Gadget Driver Installer

To make Windows select RNDIS drivers for the first function in thegadget, one needs to use the [[file:linux.inf]] file provided with thisdocument. It “attaches” Window’s RNDIS driver to the first interfaceof the gadget.

Please note, that while testing we encountered some issues[6] whenRNDIS was not the first interface. You do not need to worry abut itunless you are trying to develop your own gadget in which case watchout for this bug.

CDC ACM¶

Similarly, [[file:linux-cdc-acm.inf]] is provided for CDC ACM.

Customising the gadget¶

If you intend to hack the g_multi gadget be advised that rearrangingfunctions will obviously change interface numbers for each of thefunctionality. As an effect provided INFs won’t work since they haveinterface numbers hard-coded in them (it’s not hard to change thosethough[7]).

This also means, that after experimenting with g_multi and changingprovided functions one should change gadget’s vendor and/or product IDso there will be no collision with other customised gadgets or theoriginal gadget.

Failing to comply may cause brain damage after wondering for hours whythings don’t work as intended before realising Windows have cachedsome drivers information (changing USB port may sometimes help plusyou might try using USBDeview[8] to remove the phantom device).

INF testing¶

Provided INF files have been tested on Windows XP SP3, Windows Vistaand Windows 7, all 32-bit versions. It should work on 64-bit versionsas well. It most likely won’t work on Windows prior to Windows XPSP2.

Multifunction Composite Gadget Driver Windows 7

Other systems¶

At this moment, drivers for any other systems have not been tested.Knowing how MacOS is based on BSD and BSD is an Open Source it isbelieved that it should (read: “I have no idea whether it will”) workout-of-the-box.

For more exotic systems I have even less to say…

Any testing and drivers arewelcome!

Authors¶

This document has been written by Michal Nazarewicz([[mailto:mina86@mina86.com]]). INF files have been hacked withsupport of Marek Szyprowski ([[mailto:m.szyprowski@samsung.com]]) andXiaofan Chen ([[mailto:xiaofanc@gmail.com]]) basing on the MS RNDIStemplate[9], Microchip’s CDC ACM INF file and David Brownell’s([[mailto:dbrownell@users.sourceforge.net]]) original INF files.

Footnotes¶

[1] Remote Network Driver Interface Specification,[[https://msdn.microsoft.com/en-us/library/ee484414.aspx]].

[2] Communications Device Class Abstract Control Model, spec for thisand other USB classes can be found at[[http://www.usb.org/developers/devclass_docs/]].

[3] CDC Ethernet Control Model.

[4] [[https://msdn.microsoft.com/en-us/library/ff537109(v=VS.85).aspx]]

[5] [[https://msdn.microsoft.com/en-us/library/ff539234(v=VS.85).aspx]]

[6] To put it in some other nice words, Windows failed to respond toany user input.

[7] You may find [[http://www.cygnal.org/ubb/Forum9/HTML/001050.html]]useful.

[8] https://www.nirsoft.net/utils/usb_devices_view.html

[9] [[https://msdn.microsoft.com/en-us/library/ff570620.aspx]]

The Raspberry Pi Zero is a cool little piece of hardware with many possibilities. One of them is that it can work as a USB host OR as a USB gadget, meaning that it is possible to implement different types of devices such as ethernet, HID (keyboard, mouse, gamepad, etc.), audio, mass storage, etc. In this 3-part series of post we'll see how to configure and use a simple and generic keyboard gadget to send keys to the connected host.

In this part I'll go over the process of defining the gadget, breaking down what each different configuration files is used for and giving example values.

Edited October 12, 2017: Corrected the bmAttributes value used and added explanation for the values.

Edited July 8, 2018: Tested on Raspbian Stretch (lite) 2018-06-27.

Edited August 1, 2018: Added link to gist with gadget creation and tester scripts at the end of the post.

Edited August 13, 2019: Updated link to USB HID document.

Post series index

  1. Setup and device definition (this post)

ConfigFS

First, let's talk about ConfigFS. For this part, I'm going to reference a brilliant presentation by Matt Porter [1], which greatly summarizes the key points of ConfigFS.

In essence, ConfigFS is a virtual filesystem which exposes a userspace API for the creation of USB devices. This was introduced in Linux 3.11, and recent versions of the Raspbian operating system already include the module.

Furthermore, this allows creating several devices at the same time, meaning that the Pi can act as a composite USB device with different functionalities.

Multifunction composite gadget driver download

Usage in Raspberry Pi Zero

Multifunction Composite Gadget Driver Download

First, let's assume that we have a microSD card with the following two partitions created when writing the official Raspbian image to the card:

  • BOOT: contains the configuration applied during boot time
  • DATA: contains the filesystem of the OS

Before using ConfigFS, it is necessary to load the module. Although it should be possible to use modprobe for this, it's just easier to add the following line at the end of BOOT/config.txt:

And the following two lines at the end of DATA/etc/modules:

Once done, ConfigFS will be loaded in /sys/kernel/config/usb_gadget when the Pi is started.

Defining a USB device

The way to define a new device in ConfigFS is to create a directory inside the virtual filesystem. Note that these commands are only for illustration purposes, as they are expected to be executed during runtime. For this example, the device will be called mykeyboard:

Listing the contents of this new directory shows that several files and directories have been created automatically. The meaning of each individual file can be obtained from the official USB specification [2]. Regarding the files:

  • bcdDevice: device release number, assigned by manufacturer (format: 0x0000)
  • bcdUSB: USB specification number that the device implements (format: 0x0000)
  • bDeviceClass: USB class code, assigned by USB organization (format: 0x00)
  • bDeviceProtocol: USB protocol code, assigned by USB organization (format: 0x00)
  • bDeviceSubClass: USB subclass code, assigned by USB organization (format: 0x00)
  • bMaxPacketSize0: maximum packet size for the device, only possible values are 8, 16, 32, and 64 (format: 0x00)
  • idProduct: product ID, assigned by manufacturer (format: 0x0000)
  • idVendor: vendor ID, assigned by USB organization (format: 0x0000)
  • UDC: USB Device Controller, used to attach the gadget to the UDC driver in the machine

Note the format comment at the end of each file. This means that the file should contain the given number of hex characters. For example, if 0x0000 is shown, then the file must contain a 4-digit hexadecimal number, such as 0x12AB.

Now, let's start writing content to these files. Vendor and product IDs can be obtained from the Linux USB project [3]:

In addition, note that the following directories are also present:

  • configs/: contains specific configurations for the device
  • functions/: defines the capabilities of the virtual device
  • os_desc/: OS Descriptors (ignore it for now)
  • strings/: localized description of the device (e.g. in English)

Let's begin with the localization. For English, the hexadecimal code would be 0x409, which must be created as a directory inside strings/. Once present, it is populated with three files:

  • manufacturer : name of the manufacturer of the device
  • product: product name/description
  • serialnumber: complete serial number of the product

Therefore:

Now let's define the functions of the device. ConfigFS supports many different types of devices, but in this case we are interested in a USB keyboard. In order to have the device behave like a HID, a directory named hid.usb0 has to be created inside functions/. It contains the following files:

  • protocol: the protocol for the device
  • report_desc: binary descriptor for the reports sent by the keyboard
  • report_length: length of the reports sent by the keyboard
  • subclass: type of HID

Acer hs-usb nmea 339f (com5) driver download. For now we are going to ignore the report_desc, as I will cover that in the next post, but we can write the values for the other files, as these are common for all keyboards:

Lastly, for the configuration, creating a new directory inside configs/ will include the following:

  • MaxPower: maximum power for the device (in mA)
  • bmAttributes: configuration characteristics bitmask (in hex format: 0x00), the following bits can be set depending on the power characteristics:
    • bit 7: bus powered (e.g. 10000000)
    • bit 6: self powered (e.g. 01000000)
    • bit 5: remote wakeup (e.g. 00100000)
    • bit 4 to bit 0: reserved
  • strings/: directory for localization of the configuration description (we will use 0x409 for English, as before)

Note that it is possible to set several bits in the bmAttributes bitmask at the same time. For instance, to indicate that the device is bus powered and has remote wakeup capabilities, the bitmask should be 10100000, which in hex translates to 0xa0.

Therefore:

Once that is set up, the HID function defined previously must be linked to the configuration like so:

Activating the device

Even though we are still missing the report descriptor, the device that was just configured can be activated by attaching the gadget to a UDC driver:

After this (and after adding the report descriptor), the host to which the Pi is connected should recognize it as a USB keyboard.

TL;DR

The following script defines a USB keyboard as a gadget in ConfigFS. It should be executed by the Pi during runtime (e.g. on startup):

Bonus: The previous snippet and the test scripts used in the next posts are available at https://gist.github.com/rmed/0d11b7225b3b772bb0dd89108ee93df0

References

  • [1] https://www.elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf
  • [2] https://www.usb.org/sites/default/files/documents/hid1_11.pdf
  • [3] http://www.linux-usb.org/usb.ids

Post series index

  1. Setup and device definition (this post)