USB system device model establishment process

Publisher:PeacefulWarriorLatest update time:2016-12-03 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

USB system device model establishment process - Dust - My Electronic House

USB system device model establishment process - Dust - My Electronic House

 

USB system device model establishment process - Dust - My Electronic House

USB system device model establishment process - Dust - My Electronic House

 

USB system device model establishment process - Dust - My Electronic House

 

 


                                                         Overview of USB device model building process


The S3c2440 processor integrates a USB controller. The host controller is added to the kernel as a platform device s3c_device_usb. The device matches the driver ohci_hcd_s3c2410_driver and calls the function usb_hcd_s3c2410_probe. In the function usb_hcd_s3c2410_probe, hardware resources are obtained, memory is allocated for the USB host controller structure usb_hcd, and the function usb_add_hcd is called to fill usb_hcd. One host controller corresponds to one USB bus, and the bus is registered to the kernel usb_register_bus(&hcd->self) in the function usb_add_hcd. One host controller is bound to one root_hub. Root_hub, hub, and devices plugged into the hub port are all usb_device. Therefore, in the function usb_add_hcd, storage space usb_alloc_dev is allocated for the usb_device of the root_hub. In order to initialize the usb_device of root_hub and register it with the kernel, the function register_root_hub is called again. Whether it is root_hub, hub, or the device plugged into the hub port, they are all usb_device, so they all have device descriptors. In the function register_root_hub, the function usb_get_device_descriptor is called to obtain the device descriptor of the root_hub device. A new device needs to be configured accordingly before being added to the kernel. To complete this work, the function register_root_hub calls usb_new_device again. 

  Each USB device has one or more configurations; each configuration has one or more interfaces; an interface has one or more settings; a setting has one or more endpoints. In order to describe the configuration, interface, and endpoint, each USB device has a configuration descriptor, an interface descriptor, and an endpoint descriptor. In order to obtain and parse these descriptors, the function usb_configure_device is called in the function usb_new_device. Then the device is added to the kernel device_add(&udev->dev). Each USB device has a control endpoint. It is usually used to configure the device, obtain device information, send commands to the device, or obtain a status report of the device. It is needed in the process of device establishment. To make it work, it must be added to the kernel first. For this purpose, the function usb_create_ep_devs is called in the function usb_new_device.


The bus type of all USB devices is usb_bus_type and the device type is usb_device_type. When a USB device is added to the bus, it will look for its corresponding driver. For this purpose, the kernel creates a driver usb_generic_driver that can match all USB devices. When a usb_device is added to the kernel, it will match the driver usb_generic_driver and call the function generic_probe. In the function generic_probe, the function usb_choose_configuration will be called to select a reasonable configuration for the device. At this point, all descriptors under the selected configuration can be used to configure the device. The function usb_set_configuration completes this function. In the function usb_set_configuratio, all interfaces of the device are added to the kernel device_add(&intf->dev). The bus type of these interface devices is usb_bus_type and the device type is usb_if_device_type.


The USB interface is also added to the kernel as a device. It has its own bus usb_bus_type, so each interface has its corresponding driver. The interface is divided into HUB interface and USB device interface.


1. If it is a HUB interface:

HUB is different from devices. In addition to device descriptors, it also has its own unique HUB descriptor. There is a structure struct usb_hub to manage HUB. In order to configure HUB and fill in HUB structure usb_hub, the kernel creates HUB driver hub_driver. Once a new HUB is inserted, the driver hub_driver will match the interface of the new HUB, and then call the function hub_probe. In the function hub_probe, the memory usb_hub is allocated to the HUB structure, and the function hub_configure is called to obtain the HUB descriptor and configure the HUB. In the function hub_configure, the function get_hub_descriptor is called to obtain the HUB descriptor, and some parameters of the HUB are checked and configured for rationality. Then a URB is created and initialized as an interrupt URBusb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,hub, endpoint->bInterval);, and the interrupt callback function is hub_irq. The role of this interrupt URB will be described later. Finally, the function hub_activate is called to activate the HUB. A HUB may have multiple ports for inserting USB devices. In the function hub_activate, the status of all ports on the HUB is detected and the changes on each port are marked hub->change_bits. Finally, the interrupt URB is submitted, usb_submit_urb(hub->urb, GFP_NOIO), to wake up the kernel thread kick_khubd(hub) (discussed below).

At this point, the USB host controller and root_hub have been added to the kernel, and the entire USB system is working normally, just waiting for the USB device to be plugged into the HUB port.


2. If it is the interface of the device:

A USB device may have multiple interfaces. One interface represents a basic function. Each USB driver controls one interface. The implementation of this driver is the main work of the driver writer. After the interface device matches the corresponding driver, the probe function is called to perform the corresponding initialization device model establishment and other work. . . . . .

At this point, a USB device inserted into the HUB can work normally.


   About kernel threads:


   When registering the HUB driver usb_register(&hub_driver), a kernel thread is also created.

khubd_task = kthread_run(hub_thread, NULL, "khubd"). The job of this thread is to wake up and process changes when there are changes on the HUB port. Under normal circumstances, this thread is in sleep mode. At this time, there is no HUB to be processed on the linked list hub_event_list. So when will the thread be woken up? When the HUB is created, an interrupt URB will be created in the function hub_configure, and the HUB will be submitted in the HUB activation function hub_activate. This URB will periodically obtain the status of the HUB. Once the status on the HUB port changes, the change will be marked in the URB callback function hub_irq hub->event_bits[0] = bits, and kick_khubd(hub) will be called to add the changed HUB structure to the linked list hub_event_list to wake up the kernel thread.

 This change may be a reset, electromagnetic interference, a device plugged into or unplugged from the HUB port, etc. What we want to see is of course the change in the HUB port connection. To handle this change, the thread calls the function hub_events. In the function hub_events, call the function hub_port_status(hub, i,&portstatus, &portchange); to get the port status. Judge these changes, set the change flag, and then call the function hub_port_connect_change for processing. Determine the specific type of change in the function hub_port_connect_change and handle it accordingly. If a device is plugged into the HUB port, establish a device model for the device. Whether it is another HUB or a USB device plugged into the HUB port, there is a usb_device structure in the kernel, and the function usb_alloc_dev will be called to allocate storage space for the structure.

Call the function hub_port_init(hub, udev, port1, i) to reset the device and get its device descriptor. Then call the function usb_new_device(udev) to get the configuration descriptor, interface descriptor, endpoint descriptor, and add the device to the kernel. Then match the USB device driver usb_generic_driver to call the function generic_probe, configure the USB device, initialize the device interface and add it to the kernel. Next is the matching of each interface of the USB device with its corresponding driver. If the USB device is a HUB, match the driver hub_driver, call the function hub_probe, and establish the HUB model. If it is a device, match its corresponding driver. These tasks have been discussed above.


Reference address:USB system device model establishment process

Previous article:Kernel timer for keystroke processing
Next article:nandflash bare metal program analysis

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号