“USB overview”的版本间的差异

来自百问网嵌入式Linux wiki
第1行: 第1行:
{{DISPLAYTITLE:USB概述}}
+
This article gives information about the Linux<sup>&reg;</sup> USB framework.<br/>
 +
It explains how to activate USB interface and, based on examples, how to access it from user space.<br />
 +
<br />
  
[[Category:Linux_Operating_System]]
+
==Framework purpose==
[[Category:High_speed_interface]]
+
The USB (universal serial bus) Linux<sup>&reg;</sup> framework supports many types of:
[[Category:USB]]
+
* host controllers and peripheral devices
 +
* gadget drivers and classes to be used within a peripheral
 +
 
 +
Linux can be used on the host machine. In this case various types of peripherals can be plugged in, such as:
 +
* Mass storage (hard drive, USB stick..)
 +
* HID (keyboard, mouse..)
 +
 
 +
Linux can also be used as a device on the peripheral side, using gadget drivers. In this case, it can act as:
 +
* USB mass storage (e.g. to export some partitions, filesystem)
 +
* ethernet card
 +
* serial interface
 +
* ...
 +
 
 +
==System overview==
 +
{{
 +
ImageMap|Image:USB system overview.png {{!}} frame {{!}} center{{!}} USB Implementation architecture
 +
rect 343 437 470 487 [[#Component_description | USB controller driver]]
 +
rect 538 437 665 487 [[#Component_description | USB controller driver]]
 +
rect 343 512 470 555 [[OTG internal peripheral | OTG internal peripheral]]
 +
rect 538 512 665 555 [[USBH internal peripheral | USBH internal peripheral]]
 +
rect 538 575 665 619 [[USBPHYC internal peripheral | USBPHYC internal peripheral]]
 +
poly 342 301 479 301 479 428 404 428 404 558 342 558 [[#Component_description | USB Gadget]]
 +
poly 536 301 674 301 674 558 410 558 410 434 536 434 [[#Component_description | USB Host-Side]]
 +
}}
 +
 
 +
===Component description===
 +
* '''USB userland''' (''User space'')
 +
** ''Host-Side'' userland
 +
*:- [https://libusb.info/ libusb]<ref name="libusb">[https://libusb.info/ libusb: a cross-platform library to access USB devices]</ref> is a userland library that provides access to USB devices.
 +
*:- [https://github.com/gregkh/usbutils usbutils]<ref name="usbutils">[https://github.com/gregkh/usbutils usbutils: USB utilities for Linux, including lsusb]</ref> is a set of USB utilities for collecting information about the USB devices that are connected to the USB host. Note that '''usbutils''' depends on '''libusb'''.
 +
*:- One of the well-known utility is '''lsusb''', used to display information about USB buses and the devices connected to them.
 +
** ''Gadget'' userland
 +
*:- [https://github.com/libusbg libusbg]<ref name="libusbg">[https://github.com/libusbg libusbg: a C library encapsulating the kernel USB gadget-configfs userspace API functionality]</ref> is a userland library that provides routines for creating and parsing USB gadget devices using the configfs API.
 +
*:- {{CodeSource|Linux kernel|Documentation/usb/gadget_configfs.txt|Gadget configfs}} provides configuration interface available through user terminal, used to configure USB Gadget.
 +
** Common userland
 +
*:- '''sysfs''' provides an information interface available through the user terminal. See [[#How_to_monitor_with_sysfs | How to monitor with sysfs]] below.
 +
*:- '''debugfs''' provides a debugging interface available through the user terminal. See [[#How_to_monitor_with_debugfs | How to monitor with debugfs]] below.
 +
 
 +
* '''USB framework''' (''Kernel space''): composed of two parts, USB ''Host-Side'' and USB ''Gadget'', which rely on the USB core with specific [[#API_description | APIs]] to support USB host and devices controllers
 +
** Host-Side provides API interface to class drivers and forwards the request from class drivers to host controller driver.
 +
** Gadget requires a peripheral controller and the gadget driver to use it.
 +
 
 +
* '''USB controller drivers''' (''Kernel space'')
 +
** ''USB Host controller drivers'' such as [[USBH internal peripheral|STM32 USBH]] USB Host controllers in the USB Host-Side framework. [[USBH internal peripheral|STM32 USBH]] uses kernel community drivers (kernel space), based on the [[USB overview|USB framework]].
 +
*:- {{CodeSource|Linux kernel|drivers/usb/host/ehci-hcd.c|Enhanced Host Controller Interface (EHCI) driver}}and {{CodeSource|Linux kernel|drivers/usb/host/ehci-platform.c|Generic platform ehci driver}}
 +
*:- {{CodeSource|Linux kernel|drivers/usb/host/ohci-hcd.c|Open Host Controller Interface (OHCI) driver}}and {{CodeSource|Linux kernel|drivers/usb/host/ohci-platform.c|Generic platform ohci driver}}
 +
** ''USB OTG controller drivers'' such as [[OTG internal peripheral|STM32 OTG]] USB OTG controllers in the USB Host-Side framework when they are used either in '''otg''' or '''host''' mode, and/or in the USB Gadget framework when they are used either in '''otg''' or '''peripheral''' mode. [[OTG internal peripheral|STM32 OTG]] uses kernel community driver (kernel space), based on the [[USB overview|USB framework]].
 +
*:- {{CodeSource|Linux kernel|drivers/usb/dwc2/|DesignWare HS OTG Controller driver}}
 +
** USB controller drivers can rely on [[PHY overview|Generic PHY framework]] to manage the physical layer for USB data transmissions. [[USBPHYC internal peripheral|STM32 USBPHYC]] PHY provider is a ''PHY driver'' in the Generic PHY framework:
 +
*:- {{CodeSource|Linux kernel|drivers/phy/st/phy-stm32-usbphyc.c|STM32 USBPHYC driver}}
 +
 
 +
* '''USB hardware controllers''' (''Hardware'')
 +
USB controllers such as [[USBH internal peripheral|STM32 USBH internal peripheral]] and [[OTG internal peripheral|STM32 OTG internal peripheral]], using an on-chip High-Speed UTMI+ PHY ([[USBPHYC internal peripheral|STM32 USBPHYC internal peripheral]]), or on-chip Full-Speed PHY for [[OTG internal peripheral|STM32 OTG internal peripheral]].
 +
 
 +
* '''USB devices''' (''External USB devices'')
 +
** USB OTG specification<ref name="otg_specification">[http://www.usb.org/developers/onthego/USB_OTG_and_EH_2-0.pdf On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification]</ref> defines two roles for USB devices: A-Device and B-Device. [[OTG internal peripheral|STM32 OTG controller]], depending on the USB connector which is used, can accept both A-Device and B-Device, while [[USBH internal peripheral|STM32 USBH Host controller]] only manages B-Device:
 +
*:- '''A-Device''' is a '''power supplier''' acting as a '''USB Host''' (e.g. a PC)
 +
*:- '''B-Device''' is a '''power consumer''' and acts as a '''USB Peripheral''' (e.g. a USB key).
 +
 
 +
===API description===
 +
See [https://www.kernel.org/doc/html/latest/driver-api/usb/index.html USB kernel documentation] for more details on API functions.
 +
 
 +
==Configuration==
 +
 
 +
===Kernel configuration===
 +
USB support, [[USBH internal peripheral|STM32 USBH]] driver and [[OTG internal peripheral|STM32 OTG]] driver are activated by default in ST deliveries. Nevertheless, if a specific configuration is required, this section indicates how the USB framework can be activated/deactivated in the kernel.
 +
 
 +
Activate USB support (CONFIG_USB=y) in the kernel configuration with the Linux Menuconfig tool: [[Menuconfig or how to configure kernel]]
 +
then select:
 +
Device Drivers  --->
 +
  [*] USB support  --->
 +
Then activate USB controllers drivers.
 +
 
 +
To activate the [[USBH internal peripheral|STM32 USBH]] driver, select:
 +
Device Drivers  --->
 +
    --- USB support
 +
    <*>  Support for Host-side USB
 +
    <*>  EHCI HCD (USB 2.0) support
 +
    <*>    Generic EHCI driver for a platform device
 +
    <*>  OHCI HCD (USB 1.1) support
 +
    <*>    Generic OHCI driver for a platform device
 +
To activate the [[OTG internal peripheral|STM32 OTG]] driver, select:
 +
Device Drivers  --->
 +
    --- USB support
 +
    <*>  Support for Host-side USB
 +
    <*>  USB Gadget Support  --->
 +
    <*>  DesignWare USB2 DRD Core Support
 +
            DWC2 Mode Selection (Dual Role mode)  --->
 +
Then to activate the [[USBPHYC internal peripheral|STM32 USBPHYC]] driver, select:
 +
PHY Subsystem  --->
 +
  -*- PHY Core
 +
  <*> STMicroelectronics STM32 USB HS PHY Controller driver
 +
 
 +
===Device tree configuration===
 +
Detailed DT configurations for STM32 USB internal peripherals:
 +
* for [[USBH internal peripheral|STM32 USBH]] Host controller: [[USBH_device_tree_configuration | USBH device tree configuration]]
 +
* for [[OTG internal peripheral|STM32 OTG]] controller: [[OTG_device_tree_configuration | OTG device tree configuration]]
 +
* for [[USBPHYC internal peripheral|STM32 USBPHYC]] PHY: [[USBPHYC_device_tree_configuration | USBPHYC device tree configuration]]
 +
 
 +
==How to use the framework==
 +
===How to list USB devices===
 +
'''lsusb''' displays information about the attached USB buses and devices. <br />
 +
In the example above, we have an onboard hub, a USB mouse and USB keyboard plugged into the hub.<br />
 +
 
 +
{{Board$}} '''lsusb''' {{Highlight|/* '''root hubs''' correspond to STM32 USB controllers ([[USBH_internal_peripheral|USBH]], [[OTG_internal_peripheral| OTG]]) */}}
 +
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard
 +
Bus 002 Device 004: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse
 +
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 +
Bus 002 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
 +
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 +
 
 +
{{Board$}} '''lsusb -t''' {{Highlight|/* '''lsusb -t''' shows the USB class, the driver used and the number of ports and speed of each USB devices */}}
 +
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-platform/2p, 480M
 +
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
 +
        |__ Port 1: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
 +
        |__ Port 3: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
 +
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M
 +
 
 +
To limit '''lsusb''' to the USB keyboard:
 +
{{Board$}} '''lsusb -s 002:005''' {{Highlight|/* '''lsusb -s [Bus]:[Device]''' */}}
 +
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard
 +
{{Board$}} '''lsusb -d 413c:2003'''  {{Highlight|/* '''lsusb -d [ID]''' */}}
 +
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard
 +
 
 +
To limit '''lsusb''' to the USB keyboard and display its descriptors:
 +
{{Board$}} '''lsusb -D /dev/bus/usb/002/005'''  {{Highlight|/* '''lsusb -D /dev/bus/usb/[Bus]/[Device]''' */}}
 +
Device: ID 413c:2003 Dell Computer Corp. Keyboard
 +
Device Descriptor:
 +
  ...
 +
 
 +
===How to mount a USB key (mass-storage)===
 +
{{Board$}} mkdir /usb
 +
{{Board$}} mount /dev/sdxx /usb
 +
 
 +
===How to configure USB Gadget through configfs===
 +
See [https://www.kernel.org/doc/Documentation/usb/gadget_configfs.txt USB gadget configfs documentation] for an introduction to USB gadget configfs structure and how to use it to configure  Linux USB Gadget.
 +
 
 +
Here is an example to configure USB Gadget through configfs to use the OTG as a USB Ethernet Gadget with Remote NDIS (RNDIS). See:
 +
[https://github.com/STMicroelectronics/meta-st-openstlinux/blob/thud/recipes-bsp/tools/usbotg-gadget-config/stm32_usbotg_eth_config.sh stm32_usbotg_eth_config.sh].
 +
 
 +
==How to trace and debug the framework==
 +
 
 +
===How to monitor===
 +
====How to monitor with debugfs====
 +
Please refer to [https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#the-usb-devices the USB devices chapter]<ref>[https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#the-usb-devices  Linux USB API: The Linux-USB Host Side API - The USB devices]</ref> to decode the output.
 +
{{Board$}} '''cat /sys/kernel/debug/usb/devices'''
 +
 +
T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
 +
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
 +
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
 +
P:  Vendor=1d6b ProdID=0002 Rev= 4.14
 +
S:  Manufacturer=Linux 4.14.0 dwc2_hsotg
 +
S:  Product=DWC OTG Controller
 +
S:  SerialNumber=49000000.usb-otg
 +
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
 +
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
 +
E:  Ad=81(I) Atr=03(Int.) MxPS=  4 Ivl=256ms
 +
 +
T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=480  MxCh= 0
 +
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
 +
P:  Vendor=05e3 ProdID=0723 Rev=94.54
 +
S:  Manufacturer=Generic
 +
S:  Product=USB Storage
 +
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
 +
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
 +
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
 +
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
 +
 +
T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 2
 +
B:  Alloc=  0/800 us ( 0%), #Int=  2, #Iso=  0
 +
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
 +
P:  Vendor=1d6b ProdID=0002 Rev= 4.14
 +
S:  Manufacturer=Linux 4.14.0 ehci_hcd
 +
S:  Product=EHCI Host Controller
 +
S:  SerialNumber=5800d000.usbh-ehci
 +
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
 +
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
 +
E:  Ad=81(I) Atr=03(Int.) MxPS=  4 Ivl=256ms
 +
 +
T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480  MxCh= 4
 +
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=02 MxPS=64 #Cfgs=  1
 +
P:  Vendor=0424 ProdID=2514 Rev= b.b3
 +
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  2mA
 +
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=01 Driver=hub
 +
E:  Ad=81(I) Atr=03(Int.) MxPS=  1 Ivl=256ms
 +
I:* If#= 0 Alt= 1 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=02 Driver=hub
 +
E:  Ad=81(I) Atr=03(Int.) MxPS=  1 Ivl=256ms
 +
 +
T:  Bus=02 Lev=02 Prnt=02 Port=03 Cnt=01 Dev#=  5 Spd=1.5  MxCh= 0
 +
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
 +
P:  Vendor=413c ProdID=2003 Rev= 1.00
 +
S:  Manufacturer=Dell
 +
S:  Product=Dell USB Keyboard
 +
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
 +
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
 +
E:  Ad=81(I) Atr=03(Int.) MxPS=  8 Ivl=24ms
 +
 
 +
==== How to monitor with sysfs ====
 +
===== USB buses monitoring with sysfs =====
 +
Please refer to [http://www.linux-usb.org/FAQ.html#i6 What are the sysfs structures for Linux USB?]<ref>[http://www.linux-usb.org/FAQ.html#i6  What are the sysfs structures for Linux USB?]</ref>.
 +
{{Board$}} ls /sys/bus/usb/devices/
 +
1-0:1.0  1-1  1-1:1.0  2-0:1.0  2-1  2-1.4  2-1.4:1.0  2-1:1.0  usb1  usb2
 +
 
 +
The names that begin with '''usb''' refer to USB controllers.
 +
 
 +
The device naming scheme is the following:
 +
* bus-port{{Grey|.port}}{{Grey|.port...}} ('''1-1''', '''2-1''', or '''2-1.4''' in the example above)
 +
 
 +
The interfaces are indicated by suffixes in the following form:
 +
* :config.interface (1-1''':1.0''', 2-1''':1.0''', 2-1.4''':1.0''' in the example above)
 +
 
 +
Each interface corresponds to an entry in sysfs and can have its own driver.
 +
 
 +
===== USB Gadget monitoring with sysfs =====
 +
Once the USB Gadget is configured, USB Device Controller sysfs is populated. See {{CodeSource | Linux kernel | Documentation/ABI/stable/sysfs-class-udc}} for a description of each file.
 +
{{Board$}} ls /sys/class/udc/49000000.usb-otg/
 +
a_alt_hnp_support  device          is_selfpowered  srp
 +
a_hnp_support      function        maximum_speed  state
 +
b_hnp_enable      is_a_peripheral  power          subsystem
 +
current_speed      is_otg          soft_connect    uevent
 +
 
 +
===How to trace===
 +
==== How to trace with usbmon ====
 +
usbmon <ref>{{CodeSource | Linux kernel | Documentation/usb/usbmon.txt | usbmon}}</ref> collects traces of the input/output on the USB bus.<br/>
 +
It relies on a kernel part and on a user part, and reports the requests made by USB device drivers to the Host controller drivers.<br />
 +
Activate USBMON support (CONFIG_USB_MON=y) in the kernel configuration with Linux Menuconfig tool: [[Menuconfig or how to configure kernel]]. <br />
 +
A usbmon entry is created in debugfs. It includes several files.<br />
 +
The file names consist of a number (the USB bus - 0 relates to all buses) and a letter (s, u or t). The s file contains a generic event overview. The t (deprecated) and u files will stream trace data.<br />
 +
To gather debug data, either use the master file 0u (to capture data from all devices) or find out the bus to which your device is connected and use the corresponding bus file. For example, if the device is connected to bus 1:
 +
{{Board$}} cat /sys/kernel/debug/usb/usbmon>1u > bus1data.log
 +
To stop the capture, just type (CTRL+C) to kill the command. You can then analyze the log with [http://vusb-analyzer.sourceforge.net/ vUSBAnalyzer] graphical tool on your Linux host.
 +
 
 +
==== How to trace using a protocol analyzer ====
 +
A USB protocol analyzer is a USB traffic sniffer that decodes USB descriptors and displays bus states and packets sent. Refer to you USB protocol analyzer user manual.
 +
 
 +
===How to debug===
 +
====Activating USB framework debug messages====
 +
A detailed dynamic trace is available in [[How to use the kernel dynamic debug]]<br/>
 +
  {{Board$}} echo  "file usb* +p" > /sys/kernel/debug/dynamic_debug/control
 +
This command enables all the traces related to the USB core and drivers at runtime.<br/>
 +
A finer selection can be made by choosing only the files to trace.<br/>
 +
{{Info|Reminder: ''loglevel'' needs to be increased to 8 either by using boot arguments or by sending the ''dmesg -n 8'' command from the console}}
 +
 
 +
==== EHCI/OHCI driver debugfs entry ====
 +
EHCI/OHCI drivers export a debugfs entry when CONFIG_DYNAMIC_DEBUG is enabled.
 +
{{Board$}} ls /sys/kernel/debug/usb/ohci/5800c000.usbh-ohci/
 +
async  periodic  registers
 +
{{Board$}} ls /sys/kernel/debug/usb/ehci/5800d000.usbh-ehci/
 +
async  bandwidth  periodic  registers
 +
* '''async''' dumps a snapshot of the async schedule.
 +
* '''bandwith''' dumps the bandwidth allocation
 +
* '''periodic''' dumps a snapshot of the periodic schedule.
 +
* '''registers''' dumps the USB controller registers
 +
 
 +
==== DWC2 driver debug messages and debugfs entry====
 +
To get the verbose messages from the DWC2 driver used by [[OTG_internal_peripheral| STM32 OTG]], activate "Enable Debugging Messages" in the Linux kernel via the menuconfig [[Menuconfig or how to configure kernel]].<br/>
 +
Device Drivers  --->
 +
    [*] USB support
 +
    {{Grey|<*>  Support for Host-side USB}}
 +
    {{Grey|<*>  USB Gadget Support  --->}}
 +
    <*>  DesignWare USB2 DRD Core Support
 +
    [*]     Enable Debugging Messages
 +
    [*]       Enable Verbose Debugging Messages
 +
    [ ]    Enable Missed SOF Tracking
 +
    [*]    Enable Debugging Messages For Periodic Transfers
 +
This can be done manually in your kernel .config file:
 +
CONFIG_USB_SUPPORT=y
 +
CONFIG_USB_DWC2=y
 +
CONFIG_USB_DWC2_DEBUG=y
 +
CONFIG_USB_DWC2_VERBOSE=y
 +
CONFIG_USB_DWC2_DEBUG_PERIODIC=y
 +
The debug support for DWC2 driver (CONFIG_USB_DWC2_DEBUG) compiles all the files located in Linux kernel {{CodeSource | Linux kernel | drivers/usb/dwc2/}} folder with DEBUG flag.<br/>
 +
{{Info|Reminder: ''loglevel'' needs to be increased to 8 by using either boot arguments or the ''dmesg -n 8'' command through the console}}
 +
 
 +
The DWC2 driver also exports a debugfs entry that contains useful information:
 +
{{Board$}} ls /sys/kernel/debug/49000000.usb-otg/
 +
dr_mode  ep0  ep1in  ep1out  ep2in  ep2out  ep3in  ep3out  ep4in  ep4out  ep5in  ep5out  ep6in  ep6out  ep7in  ep7out  ep8in  ep8out  fifo  hw_params  params  regdump state  testmode
 +
* '''dr_mode''' indicates the working mode of the USB controller. It can be "host", "peripheral" or "otg". The value is set through a device tree property.
 +
* '''ep*''' files show the state of the given endpoint.
 +
* '''fifo''' shows the FIFO information for the overall FIFO and all the periodic transmission FIFOs.
 +
* '''hw_params''' shows the parameters read from USB controller registers.
 +
* '''params''' shows the parameters used by the driver.
 +
* '''regdump''' dumps all the USB controller registers.
 +
* '''state''' shows the overall state of the hardware controller and some general information on the available endpoints.
 +
* '''testmode''' shows/sets usb test mode ("test_j", "test_k", "test_se0_nak", "test_packet", "test_force_enable").
 +
 
 +
==Source code location==
 +
The source files are located inside the Linux kernel.
 +
* The '''USB framework''' is under {{CodeSource | Linux kernel | drivers/usb/}}
 +
* The drivers used for [[USBH internal peripheral | STM32 USBH]] are under {{CodeSource | Linux kernel | drivers/usb/host/ehci-platform.c}}, {{CodeSource | Linux kernel | drivers/usb/host/ehci-hcd.c}} and {{CodeSource | Linux kernel | drivers/usb/host/ohci-platform.c}}, {{CodeSource | Linux kernel | drivers/usb/host/ohci-hcd.c}}
 +
* The driver used for [[OTG internal peripheral | STM32 OTG]] is under {{CodeSource | Linux kernel | drivers/usb/dwc2/}}
 +
 
 +
==References==
 +
<references />
 +
 
 +
<noinclude>
 +
{{ArticleBasedOnModel | Framework overview article model}}
 +
{{PublicationRequestId | 10664 | 2019-02-18 | AnneJ}}
 +
[[Category:USB|0]]
 +
</noinclude>

2020年5月8日 (五) 00:03的版本

This article gives information about the Linux® USB framework.
It explains how to activate USB interface and, based on examples, how to access it from user space.

Framework purpose

The USB (universal serial bus) Linux® framework supports many types of:

  • host controllers and peripheral devices
  • gadget drivers and classes to be used within a peripheral

Linux can be used on the host machine. In this case various types of peripherals can be plugged in, such as:

  • Mass storage (hard drive, USB stick..)
  • HID (keyboard, mouse..)

Linux can also be used as a device on the peripheral side, using gadget drivers. In this case, it can act as:

  • USB mass storage (e.g. to export some partitions, filesystem)
  • ethernet card
  • serial interface
  • ...

System overview

USB controller driver USB controller driver OTG internal peripheral USBH internal peripheral USBPHYC internal peripheral USB Gadget USB Host-Side
USB Implementation architecture

Component description

  • USB userland (User space)
    • Host-Side userland
    - libusb[1] is a userland library that provides access to USB devices.
    - usbutils[2] is a set of USB utilities for collecting information about the USB devices that are connected to the USB host. Note that usbutils depends on libusb.
    - One of the well-known utility is lsusb, used to display information about USB buses and the devices connected to them.
    • Gadget userland
    - libusbg[3] is a userland library that provides routines for creating and parsing USB gadget devices using the configfs API.
    - |}} Gadget configfs provides configuration interface available through user terminal, used to configure USB Gadget.
    • Common userland
    - sysfs provides an information interface available through the user terminal. See How to monitor with sysfs below.
    - debugfs provides a debugging interface available through the user terminal. See How to monitor with debugfs below.
  • USB framework (Kernel space): composed of two parts, USB Host-Side and USB Gadget, which rely on the USB core with specific APIs to support USB host and devices controllers
    • Host-Side provides API interface to class drivers and forwards the request from class drivers to host controller driver.
    • Gadget requires a peripheral controller and the gadget driver to use it.
  • USB hardware controllers (Hardware)

USB controllers such as STM32 USBH internal peripheral and STM32 OTG internal peripheral, using an on-chip High-Speed UTMI+ PHY (STM32 USBPHYC internal peripheral), or on-chip Full-Speed PHY for STM32 OTG internal peripheral.

  • USB devices (External USB devices)
    • USB OTG specification[4] defines two roles for USB devices: A-Device and B-Device. STM32 OTG controller, depending on the USB connector which is used, can accept both A-Device and B-Device, while STM32 USBH Host controller only manages B-Device:
    - A-Device is a power supplier acting as a USB Host (e.g. a PC)
    - B-Device is a power consumer and acts as a USB Peripheral (e.g. a USB key).

API description

See USB kernel documentation for more details on API functions.

Configuration

Kernel configuration

USB support, STM32 USBH driver and STM32 OTG driver are activated by default in ST deliveries. Nevertheless, if a specific configuration is required, this section indicates how the USB framework can be activated/deactivated in the kernel.

Activate USB support (CONFIG_USB=y) in the kernel configuration with the Linux Menuconfig tool: Menuconfig or how to configure kernel then select:

Device Drivers  --->
 [*] USB support  --->

Then activate USB controllers drivers.

To activate the STM32 USBH driver, select:

Device Drivers  --->
   --- USB support
   <*>   Support for Host-side USB
   <*>   EHCI HCD (USB 2.0) support
   <*>     Generic EHCI driver for a platform device
   <*>   OHCI HCD (USB 1.1) support
   <*>     Generic OHCI driver for a platform device

To activate the STM32 OTG driver, select:

Device Drivers  --->
   --- USB support
   <*>   Support for Host-side USB
   <*>   USB Gadget Support  --->
   <*>   DesignWare USB2 DRD Core Support
           DWC2 Mode Selection (Dual Role mode)  --->

Then to activate the STM32 USBPHYC driver, select:

PHY Subsystem  --->
  -*- PHY Core
  <*> STMicroelectronics STM32 USB HS PHY Controller driver

Device tree configuration

Detailed DT configurations for STM32 USB internal peripherals:

How to use the framework

How to list USB devices

lsusb displays information about the attached USB buses and devices.
In the example above, we have an onboard hub, a USB mouse and USB keyboard plugged into the hub.

Board $> lsusb							/* root hubs correspond to STM32 USB controllers (USBH,  OTG) */
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard
Bus 002 Device 004: ID 046d:c016 Logitech, Inc. Optical Wheel Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Board $> lsusb -t 	 	 	 	 	 	/* lsusb -t shows the USB class, the driver used and the number of ports and speed of each USB devices */
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-platform/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 1: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 3: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M

To limit lsusb to the USB keyboard:

Board $> lsusb -s 002:005 	 				/* lsusb -s [Bus]:[Device] */
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard
Board $> lsusb -d 413c:2003  	 			 	/* lsusb -d [ID] */
Bus 002 Device 005: ID 413c:2003 Dell Computer Corp. Keyboard

To limit lsusb to the USB keyboard and display its descriptors:

Board $> lsusb -D /dev/bus/usb/002/005  	 		/* lsusb -D /dev/bus/usb/[Bus]/[Device] */
Device: ID 413c:2003 Dell Computer Corp. Keyboard
Device Descriptor:
 ...

How to mount a USB key (mass-storage)

Board $> mkdir /usb
Board $> mount /dev/sdxx /usb

How to configure USB Gadget through configfs

See USB gadget configfs documentation for an introduction to USB gadget configfs structure and how to use it to configure Linux USB Gadget.

Here is an example to configure USB Gadget through configfs to use the OTG as a USB Ethernet Gadget with Remote NDIS (RNDIS). See: stm32_usbotg_eth_config.sh.

How to trace and debug the framework

How to monitor

How to monitor with debugfs

Please refer to the USB devices chapter[5] to decode the output.

Board $> cat /sys/kernel/debug/usb/devices

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.14
S:  Manufacturer=Linux 4.14.0 dwc2_hsotg
S:  Product=DWC OTG Controller
S:  SerialNumber=49000000.usb-otg
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  4 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=05e3 ProdID=0723 Rev=94.54
S:  Manufacturer=Generic 
S:  Product=USB Storage
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 2
B:  Alloc=  0/800 us ( 0%), #Int=  2, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.14
S:  Manufacturer=Linux 4.14.0 ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=5800d000.usbh-ehci
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480  MxCh= 4
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=02 MxPS=64 #Cfgs=  1
P:  Vendor=0424 ProdID=2514 Rev= b.b3
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  2mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=01 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms
I:* If#= 0 Alt= 1 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=02 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms

T:  Bus=02 Lev=02 Prnt=02 Port=03 Cnt=01 Dev#=  5 Spd=1.5  MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=413c ProdID=2003 Rev= 1.00
S:  Manufacturer=Dell
S:  Product=Dell USB Keyboard
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 70mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=24ms

How to monitor with sysfs

USB buses monitoring with sysfs

Please refer to What are the sysfs structures for Linux USB?[6].

Board $> ls /sys/bus/usb/devices/
1-0:1.0  1-1  1-1:1.0  2-0:1.0  2-1  2-1.4  2-1.4:1.0  2-1:1.0  usb1  usb2

The names that begin with usb refer to USB controllers.

The device naming scheme is the following:

  • bus-port.port.port... (1-1, 2-1, or 2-1.4 in the example above)

The interfaces are indicated by suffixes in the following form:

  • :config.interface (1-1:1.0, 2-1:1.0, 2-1.4:1.0 in the example above)

Each interface corresponds to an entry in sysfs and can have its own driver.

USB Gadget monitoring with sysfs

Once the USB Gadget is configured, USB Device Controller sysfs is populated. See Documentation/ABI/stable/sysfs-class-udc| |}} Documentation/ABI/stable/sysfs-class-udc for a description of each file.

Board $> ls /sys/class/udc/49000000.usb-otg/
a_alt_hnp_support  device           is_selfpowered  srp
a_hnp_support      function         maximum_speed   state
b_hnp_enable       is_a_peripheral  power           subsystem
current_speed      is_otg           soft_connect    uevent

How to trace

How to trace with usbmon

usbmon [7] collects traces of the input/output on the USB bus.
It relies on a kernel part and on a user part, and reports the requests made by USB device drivers to the Host controller drivers.
Activate USBMON support (CONFIG_USB_MON=y) in the kernel configuration with Linux Menuconfig tool: Menuconfig or how to configure kernel.
A usbmon entry is created in debugfs. It includes several files.
The file names consist of a number (the USB bus - 0 relates to all buses) and a letter (s, u or t). The s file contains a generic event overview. The t (deprecated) and u files will stream trace data.
To gather debug data, either use the master file 0u (to capture data from all devices) or find out the bus to which your device is connected and use the corresponding bus file. For example, if the device is connected to bus 1:

Board $> cat /sys/kernel/debug/usb/usbmon>1u > bus1data.log

To stop the capture, just type (CTRL+C) to kill the command. You can then analyze the log with vUSBAnalyzer graphical tool on your Linux host.

How to trace using a protocol analyzer

A USB protocol analyzer is a USB traffic sniffer that decodes USB descriptors and displays bus states and packets sent. Refer to you USB protocol analyzer user manual.

How to debug

Activating USB framework debug messages

A detailed dynamic trace is available in How to use the kernel dynamic debug

 Board $> echo  "file usb* +p" > /sys/kernel/debug/dynamic_debug/control

This command enables all the traces related to the USB core and drivers at runtime.
A finer selection can be made by choosing only the files to trace.

Info.png Reminder: loglevel needs to be increased to 8 either by using boot arguments or by sending the dmesg -n 8 command from the console

EHCI/OHCI driver debugfs entry

EHCI/OHCI drivers export a debugfs entry when CONFIG_DYNAMIC_DEBUG is enabled.

Board $> ls /sys/kernel/debug/usb/ohci/5800c000.usbh-ohci/
async  periodic  registers
Board $> ls /sys/kernel/debug/usb/ehci/5800d000.usbh-ehci/
async  bandwidth  periodic  registers
  • async dumps a snapshot of the async schedule.
  • bandwith dumps the bandwidth allocation
  • periodic dumps a snapshot of the periodic schedule.
  • registers dumps the USB controller registers

DWC2 driver debug messages and debugfs entry

To get the verbose messages from the DWC2 driver used by STM32 OTG, activate "Enable Debugging Messages" in the Linux kernel via the menuconfig Menuconfig or how to configure kernel.

Device Drivers  --->
   [*] USB support
   <*>   Support for Host-side USB
   <*>   USB Gadget Support  --->
   <*>   DesignWare USB2 DRD Core Support
   [*]     Enable Debugging Messages
   [*]       Enable Verbose Debugging Messages
   [ ]     Enable Missed SOF Tracking
   [*]     Enable Debugging Messages For Periodic Transfers

This can be done manually in your kernel .config file:

CONFIG_USB_SUPPORT=y
CONFIG_USB_DWC2=y
CONFIG_USB_DWC2_DEBUG=y
CONFIG_USB_DWC2_VERBOSE=y
CONFIG_USB_DWC2_DEBUG_PERIODIC=y

The debug support for DWC2 driver (CONFIG_USB_DWC2_DEBUG) compiles all the files located in Linux kernel drivers/usb/dwc2/| |}} drivers/usb/dwc2/ folder with DEBUG flag.

Info.png Reminder: loglevel needs to be increased to 8 by using either boot arguments or the dmesg -n 8 command through the console

The DWC2 driver also exports a debugfs entry that contains useful information:

Board $> ls /sys/kernel/debug/49000000.usb-otg/
dr_mode  ep0  ep1in  ep1out  ep2in  ep2out  ep3in  ep3out  ep4in  ep4out  ep5in  ep5out  ep6in  ep6out  ep7in  ep7out  ep8in  ep8out  fifo  hw_params  params  regdump state  testmode
  • dr_mode indicates the working mode of the USB controller. It can be "host", "peripheral" or "otg". The value is set through a device tree property.
  • ep* files show the state of the given endpoint.
  • fifo shows the FIFO information for the overall FIFO and all the periodic transmission FIFOs.
  • hw_params shows the parameters read from USB controller registers.
  • params shows the parameters used by the driver.
  • regdump dumps all the USB controller registers.
  • state shows the overall state of the hardware controller and some general information on the available endpoints.
  • testmode shows/sets usb test mode ("test_j", "test_k", "test_se0_nak", "test_packet", "test_force_enable").