Главная> Блог> What is the structure of USB in Linux? What are USB Core and Hub?

What is the structure of USB in Linux? What are USB Core and Hub?

September 28, 2023

USB cannot be explained clearly in just one article. If you want to study USB in depth, the USB protocol (plus Host and OTG protocol) is necessary knowledge. In addition, there is a book in China> and it is well written in detail (click to read the original text, 21ic embedded forum has a download), the only flaw It is too detailed, but I feel that the idea structure is not very clear. Today we will briefly sort out the structure of USB in Linux, focusing on the analysis of USB Core and Hub.

0. Preliminary Theory

To be honest, it is quite painful to read the USB protocol. It is just a protocol, a game rule established in the USB world, just like legal provisions. It is not written for learners and is very readable. Here is a summary of the following key and basic points.

0.1 Topology (ch4.1.1)

· The reason for specifying this tree topology is to avoid ring connections.

· One USB bus has one and only one USB Host, corresponding to one RootHub

· USB devices are divided into two categories, Hub and Functions. Hub connects more USB devices through the port. Functions are USB external slave devices.

· Up to 7 levels, and the seventh level cannot have Hubs, only functions.

· Compound Device-Connect multiple devices to a Hub to form a small device.

· Composite Device-A USB external device has multiple multiplexing functions.

0.2 Mechanical properties (ch5)

· The connector is the connection port on the device.

· The plug is the socket at both ends of the USB cable.

· Mini-AB, Micro-AB refer to connectors that support two types of plugs A and B.

0.3 Electrical performance (ch6)

· VBUS-+5V power supply.

· D+ D--cable used for data transmission.

· Low-speed 10-100Kb/s for mouse and keyboard

· Full-speed 500Kb-10Mb/s applied to audio and microphone

· High-speed high-speed 25-400Mb/s applied to storage and video (USB3.0 is 10 times the block)

0.4 Four Descriptors (ch9.5)

The protocol stipulates four USB descriptors-device device, configuration, interface, and endpoint.

Enter the command in the terminal # ls /sys/bus/usb/devices

usb1 1-0:1.0 usb2 2-0:1.0 //USB bus (RootHub) No.2, USB port No.0, configuration No.1, interface No.0.

· Distinguish between port and endpoint, port and hub, endpoint is the endpoint necessary for each USB device for data transmission.

· Device device>configuration>interface>setting>endpoint endpoint.

· The device can have multiple configurations, the configuration can have one or more interfaces, and the interface can have one or more settings.

· An interface corresponds to a driver, and an interface is a collection of endpoints.

0.5 Start process (ch9.1, 9.2)

· Attached->powered->default->address->configured

· The biggest difference between the startup process and other devices such as SD cards is the Hub. The host judges the presence of USB external devices based on the status of the Hub.

· The entire implementation process of USB external device insertion and removal is called Bus Enumeration.

0.6 Data streaming (ch5)

Endpoint is divided into zero endpoint and non-zero endpoint. Zero endpoint is used as the default control method to initialize and control USB logic devices.

· Data stream transfer is divided into control/bulk/interrupt/isochronous data transfer.

0.7 packet (ch8)

· Data packets are divided into Token, Data, Handshake, and Special. The four packets have their own data organization methods.

· Token packet can only be sent from the host to the device, divided into IN, OUT, SOF and SETUP.

· The SETUP packet implements the request sent by the host to the device, and must also meet a specific format. (ch9.3,9.4)

1. USB Core

To answer a question that has troubled me for a long time, how much do I need to read when reading Linux source code? This is an eternal topic, and everyone in the same group has their own opinions. In my opinion, how to read the source code mainly depends on one's career position, whether it is R&D or development, whether to contribute to the Linux community or to develop with existing solutions? I think most drive engineers belong to the latter. Then, in the face of the well-developed core layer source code, is it still necessary to look at it, or is it necessary to study in depth? I think that since we have stood on the shoulders of giants, we must at least know how this broad shoulder is made, its value and how to use it.

In that case, what exactly is the USB core layer, what does it do silently, and how do we use it? There are two main points here, USB bus and urb.

1.1 USB subsystem structure

According to the agreement, HCD provides hardware abstraction driven by the main controller. It is only responsible for the USB Core. The USB Core maps the user's request to the relevant HCD, and the user cannot directly access the HCD. In other words, USB Core is the only bridge between HCD and USB devices.

1.2 Initialization of the USB subsystem

The USB core source code is located at ./drivers/usb/core, and the Makefile summary is as follows,

The usbcore module does not represent a certain device, but the module on which all USB devices depend. It is the USB subsystem.

Initialization is implemented in ./drivers/usb/core/usb.c, the pseudo code is as follows,

usbcore has registered USB bus, USB file system, USB Hub and USB generic driver, etc.

1.3 USB bus

Register the USB bus through bus_register(&usb_bus_type);

struct bus_type usb_bus_type = {.name = "usb", .match = usb_device_match, // This is a very important function to match USB devices and drivers. .uevent = usb_uevent, .pm = &usb_bus_pm_ops,}; The following summarizes the entire process of USB device and driver matching,

-> step 1-usb device driver

When the USB subsystem is initialized, it will register usb_generic_driver. Its structure type is usb_device_driver. It is the only USB device driver in the USB world, which is different from the struct usb_driver USB driver.

· There is only one USB device driver, that is, the object usb_generice_driver. All USB devices must be bound to usb_generic_driver. Its mission can be summarized as: select a suitable configuration for the USB device and let the device enter the configured state .

· USB driver (usb driver) is the interface driver of USB device, such as adb driver, u disk driver, mouse driver and so on.

-> step 2-usb driver

Register the USB driver when Linux starts, and submit a device model to the USB driver via usb_register() in xxx_init() and add it to the driver chain list of the USB bus.

-> step 3-usb device

The USB device is connected to the Hub, and the Hub detects that a device is connected, assigns a struct usb_device structure object to the device, and adds the device to the USB device list.

-> step 4-usb interface

The detailed information of each configuration of the USB device has been obtained during the long journey in the USB core and stored in several related members.

usb_generic_driver gets the detailed information of the USB device, and then sends the prepared interface to the device model. The Linux device model adds the interface to the device link list, and then polls another drive link list of the USB bus to call for each driver found The match function of the USB bus completes the match.

1.4 USB Request Block (urb)

The communication between the USB host and the device is transmitted in the form of packets. The idea of ​​Linux is to encapsulate these protocol-compliant data into data blocks for unified scheduling. The USB data block is urb, and the structure struct urb , Defined in, the member unsigned char *setup_packet pointer points to the SETUP packet. The following is a summary of the process of using urb to complete a complete USB communication.

-> step 1-usb_alloc_urb()

Create a urb and specify the destination endpoint of the USB device.

-> step 2-usb_control_msg()

Submit the urb to the USB core, and the USB core hands it to the HCD host controller driver.

-> step 3-usb_parse_configuration()

HCD parses the urb, gets the data and communicates with the USB device.

-> step 4

HCD returns the ownership of the urb to the driver.

The most important function in the protocol layer is usb_control/bulk/interrupt_msg(), here is a simple clue,

usb_control_msg() => usb_internal_control_msg() => usb_start_wait_urb() => usb_submit_urb() => usb_hcd_submit_urb => hcd->driver->urb_enqueue() The HCD main controller driver implements USB data communication according to the specific platform.

2. USB Hub

Hub is used to connect more USB devices. The hardware realizes the bus enumeration process of USB devices, and the software realizes the matching of USB devices and interfaces on the USB bus.

The following summarizes the implementation mechanism of USB Hub in the Linux USB core layer.

When the USB subsystem is initialized, usb_hub_init() starts a kernel thread named "khubd",

The kernel thread khubd serves the USB Hub from start to end after Linux starts. When there is no Hub event, khubd goes to sleep. When a USB Hub event is triggered, it will be triggered by hud_irq() => hub_activate() => kick_khubd(). Join the hub_event_list list and execute hub_events(). hub_events() will continuously poll the hub_events_list list to complete the events triggered by the hub until the end of the exit when the list is empty, and return to wait_event_xxx to continue waiting.

The whole process of handling hub events can be roughly divided into two steps.

· The first step is to determine the port status change

Obtain the status of the hub port through hub_port_status().

In the source code, similar functions like hub_port_status(), hub_hub_status(), etc., all call the core layer usb_control_msg() to realize the communication between the main controller and the USB device.

· The second step to deal with port changes

hub_port_connect_change() is the core function. Take the port discovering that a new USB device is inserted as an example. The USB Hub does the following important tasks for the USB device. Note that the so-called USB device here refers to the external USB device inserted into the USB Hub (including Hub and Functions), and then Hub is serving USB devices.

1) usb_alloc_dev() applies for a sturct usb_device structure for the USB device.

2) usb_set_device_state() Set the USB device state to the power-on state. (The device has entered the powered state on the hardware).

3) choose_address() Choose an address for the USB device, and use a polling algorithm to choose an address number from 0-127 for the device.

4) The hub_port_init() port initialization is essentially to obtain the device descriptor.

5) usb_get_status() This is a bit special, it is specially prepared for Hub and external Hub.

6) usb_new_device() At this time, the USB device has entered the Configured state. Call device_add() to find the driver on the USB bus. If the match is successful, load the corresponding driver.

3. USB OTG

The concept of OTG is introduced to allow devices to act as master and slave. The master device is HCD, and the slave device is UDC, or Gadget. Here is a brief review of the agreement and source code.

3.1 Agreement

1) Protocol

There are three types of OTG transmission protocols-ADP, SRP, and HNP.

· ADP (Attach Detection Protocol) When there is no power supply on the USB bus, ADP allows OTG devices or USB devices to determine the connection status.

· SRP (Session Request Protocol) allows the slave device to also control the master device.

· HNP (Host Negotiation Protocol) allows two devices to exchange master and slave roles.

2) Device role

The protocol defines two roles, OTG A-device and OTG B-device. A-device is the power provider and B-device is the power consumer. In the default configuration, A-device is the master device and B-device is the slave device. It can be exchanged through HNP later.

3) OTG micro plug

The agreement says "An OTG product must have a single Micro-AB receptacle and no other USB receptacles." This sentence is a bit problematic. . . It should also include mini-AB receptacle, all of the following micro can be mini.

One end of the OTG cable is a micro-A plug and the other end is a micro-B plug.

OTG adds a fifth pin named ID-pin, the ID-pin of the micro-A plug is grounded, and the ID-pin of the micro-B plug is suspended.

An OTG device is called a micro-A device when connected to a micro-A plug, and called a micro-B device when connected to a micro-B plug.

3.2 Analysis of source code

The OTG controller is integrated in the CPU, and the source code drivers under Linux are provided by various development platforms, located under ./drivers/usb/otg/.

Take the Freescale platform as an example. The main idea is to generate an interrupt when an OTG line is inserted into the OTG device. The upper half of the interrupt handling function determines whether the OTG device belongs to the Host (HCD) or Gadget (UDC) by reading the corresponding value of the OTG controller register. , The lower part of the work queue is restarted by a callback function like host->resume() or gadget->resume() to restart the Host or Gadget controller. The specific implementation process of resume() is implemented in the HCD or UDC related driver.

4. USB Host

The USB host controller (HCD) is also integrated in the CPU and is driven by the development platform manufacturer. The source code is located under ./drivers/usb/host/.

There are four main types of main controllers: EHCI, FHCI, OHCI, UHCI. Their respective register interface protocols are different, and most embedded devices are EHCI.

The structure type of the driver is struct hc_driver. The member (*urb_enqueue) is the most important. It is the core implementation function of the host controller HCD to transfer the data packet urb to the USB device. As mentioned before, the most important in the protocol layer The function usb_control_msg() will eventually call back the (*urb_enqueue) of the main controller.

usb_control_msg() => usb_internal_control_msg() => usb_start_wait_urb() => usb_submit_urb() => usb_hcd_submit_urb => hcd->driver->urb_enqueue()

5. USB Gadget

The Gadget source code is located under ./drivers/usb/gadget/, which involves relatively many drivers and data structures.

The main drivers are,

· Platform-related Gadget controller driver

· Platform-independent multiplexed device driver composite.c

· Android platform multiplexing device driver android.c

· Adb driver f_adb.c, U disk driver f_mass_storage.c and other multiplexed USB drivers

The data structure mainly includes,

· Struct usb_gadget mainly contains (*ops) and struct usb_ep *ep0.

· In struct usb_gadget_driver, (*bind) binds the multiplexed device driver, and (*setup) completes the USB enumeration operation.

· The (*bind) binding in struct usb_compostie_driver, such as android multiplexing device driver.

· Struct usb_request USB data request packet, similar to urb.

· Struct usb_configuration is the configuration of this gadget, and the array of struct usb_function *interface[] records the USB interface/function/drive it has.

· In struct usb_function (*bind) binds the related USB interface, (*setup) completes the USB enumeration operation.

The overall framework can be summarized as, (mv_gadget is the data of the gadget controller)

6. USB Mass Storage

There is only one Linux U disk drive in the world, located at ./drivers/usb/storage/usb.c. The pseudo code is as follows. It should be noted here that before the initialization probe of the U disk drive, the USB core and hub have been Disk has done two major tasks, namely

1) The enumeration of the USB device is completed. At this time, the U disk has entered the configured state, and the U disk data is stored in struct usb_interface.

2) The matching of the device and the driver on the USB bus is completed. At this time, the driver corresponding to the interface has been found on the bus, namely the U disk drive.

· The khaki part is encapsulated by the SCSI subsystem to realize the final U disk drive registration.

· Usb_stor_scan_thread scans the thread of the U disk and waits for 5 seconds. If it is not removed within 5 seconds, the SCSI will perform a full scan.

· Usb_stor_contro_thread is a core thread, please refer to "USB Things"...

Связаться с нами

Author:

Ms. Amy

Электронная почта:

amy@ucoax.com

Phone/WhatsApp:

+8613913156783

Популярные продукты
Новости промышленности
You may also like
Related Categories

Письмо этому поставщику

Тема:
Электронная Почта:
сообщение:

Your message must be betwwen 20-8000 characters

Связаться с нами

Author:

Ms. Amy

Электронная почта:

amy@ucoax.com

Phone/WhatsApp:

+8613913156783

Популярные продукты
Новости промышленности

Контакты

  • Номер Телефона : 86-0512-66610280
  • Мобильный Телефон: +8613913156783
  • Электронная Почта: amy@ucoax.com
  • Адрес Компании : NO.288 HUAFENG ROAD, Suzhou, Jiangsu China

Отправить Запрос

Список сопутствующих товаров

Подписывайтесь на нас

Copyright © 2024 UCOAXВсе права защищены.
We will contact you immediately

Fill in more information so that we can get in touch with you faster

Privacy statement: Your privacy is very important to Us. Our company promises not to disclose your personal information to any external company with out your explicit permission.

Отправить