USB驱动的组成有哪些?
- 提问者网友:轻浮
- 2021-04-12 10:39
- 五星知识达人网友:野慌
- 2021-04-12 12:03
在USB规范中把USB分为五个部分:控制器、控制器驱动程序、USB芯片驱动程序、USB设备和针对不同USB设备的客户驱动程序。
第一、 USB芯片驱动程序:这部分组件主要是可以提供对USB的支持。
第二、 USB控制器驱动程序:这部分主要是在控制器和USB设备之间建立通信信道。
第三、 USB设备:这部分组件包括和PC相连的USB外围设备,主要分为:设备本身可以再接上其它的USB外围设备,另外设备本身不能再连接其它外围设备。即集线器和设备。也可以说集线器是带有连接其它外围设备的USB端口,设备是连接在计算机上的用语完成特定功能而且符合USB规范的设备单元。
第四、 USB控制器:这部分主要负责执行由USB控制器驱动程序发出的命令。
第五、 USB设备驱动程序:这部分组件主要是用来驱动USB设备的程序,一般来说这是由操作系统或者是USB设备制造商提供
- 1楼网友:人類模型
- 2021-04-12 13:28
硬件
- 2楼网友:归鹤鸣
- 2021-04-12 13:07
下面讲解/sys/bus/usb目录的树形结构实例,其中的多数文件都是到/sys/devices及/sys/drivers中相应文件的链接。
usb |-- devices | |-- 1-0:1.0 -> ../../../devices/pci0000:00/0000:00:07.2/usb1/1-0:1.0 | |-- 1-1 -> ../../../devices/pci0000:00/0000:00:07.2/usb1/1-1 | |-- 1-1:1.0 -> ../../../devices/pci0000:00/0000:00:07.2/usb1/1-1/1-1:1.0 | '-- usb1 -> ../../../devices/pci0000:00/0000:00:07.2/usb1 '-- drivers |-- hub | |-- 1-0:1.0 -> ../../../../devices/pci0000:00/0000:00:07.2/usb1/1-0:1.0 | |-- bind | |-- module -> ../../../../module/usbcore | '-- unbind |-- usb | |-- 1-1 -> ../../../../devices/pci0000:00/0000:00:07.2/usb1/1-1 | |-- bind | |-- module -> ../../../../module/usbcore | |-- unbind | '-- usb1 -> ../../../../devices/pci0000:00/0000:00:07.2/usb1 '-- usbfs |-- bind |-- module -> ../../../../module/usbcore '-- unbind |
正如tty_driver、pci_driver等,在Linux内核中,使用usb_driver结构体描述一个USB设备驱动,usb_driver结构体的定义如代码清单20.11所示。
代码清单20.11 usb_driver结构体
1 struct usb_driver { 2 const char *name; 4 int (*probe) (struct usb_interface *intf, 5 const struct usb_device_id *id); 7 void (*disconnect) (struct usb_interface *intf); 9 int (*ioctl) (struct usb_interface *intf, unsigned int code, 10 void *buf); 12 int (*suspend) (struct usb_interface *intf, pm_message_t message); 13 int (*resume) (struct usb_interface *intf); 15 void (*pre_reset) (struct usb_interface *intf); 16 void (*post_reset) (struct usb_interface *intf); 18 const struct usb_device_id *id_table; 20 struct usb_dynids dynids; 21 struct usbdrv_wrap drvwrap; 22 unsigned int no_dynamic_id:1; 23 unsigned int supports_autosuspend:1; 24 }; |
在编写新的USB设备驱动时,主要应该完成的工作是probe()和disconnect()函数,即探测和断开函数,它们分别在设备被插入和拔出的时候被调用,用于初始化和释放软硬件资源。对usb_driver的注册和注销通过这两个函数完成:
int usb_register(struct usb_driver *new_driver) void usb_deregister(struct usb_driver *driver); |
usb_driver结构体中的id_table成员描述了这个USB驱动所支持的USB设备列表,它指向一个usb_device_id数组,usb_device_id结构体用于包含USB设备的制造商ID、产品ID、产品版本、设备类、接口类等信息及其要匹配标志成员match-Flash(标明要与哪些成员匹配)。可以借助下面一组宏来生成usb_device_id结构体的实例:
USB_DEVICE(vendor, product) |
该宏根据制造商ID和产品ID生成一个usb_device_id结构体的实例,在数组中增加该元素将意味着该驱动可支持匹配制造商ID、产品ID的设备。
USB_DEVICE_VER(vendor, product, lo, hi) |
该宏根据制造商ID、产品ID、产品版本的最小值和最大值生成一个usb_device_id结构体的实例,在数组中增加该元素将意味着该驱动可支持匹配制造商ID、产品ID和lo~hi范围内版本的设备。
USB_DEVICE_INFO(class, subclass, protocol) |
该宏用于创建一个匹配设备指定类型的usb_device_id结构体实例。
USB_INTERFACE_INFO(class, subclass, protocol) |
该宏用于创建一个匹配接口指定类型的usb_device_id结构体实例。
代码清单20.12所示为两个用于描述某USB驱动所支持的USB设备的usb_device_id结构体数组实例。
代码清单20.12 usb_device_id结构体数组实例
1 2 3 4 static struct usb_device_id id_table [] = { 5 { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, 6 { }, 7 }; 8 MODULE_DEVICE_TABLE (usb, id_table); 9 10 11 static struct usb_device_id id_table [] = { 12 { .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, }, 13 { }, 14 }; 15 MODULE_DEVICE_TABLE (usb, id_table); |
上述usb_driver结构体中的函数是USB设备驱动中USB相关的部分,而USB只是一个总线,真正的USB设备驱动的主体工作仍然是USB设备本身所属类型的驱动,如字符设备、tty设备、块设备、输入设备等。因此USB设备驱动包含其作为总线上挂在设备的驱动和本身所属设备类型的驱动两部分。
与platform_driver类似,usb_driver起到了"牵线"的作用,即在probe()里注册相应的字符、tty等设备,在disconnect()注销相应的字符、tty等设备,而原先对设备的注册和注销一般直接发生在模块加载和卸载函数中。
尽管USB本身所属设备驱动的结构与其不挂在USB总线上时完全相同,但是在访问方式上却发生了很大的变化,例如,对于字符设备而言,尽管仍然是write()、read()、ioctl()这些函数,但是在这些函数中,与USB设备通信时不再是I/O内存和I/O端口的访问,而贯穿始终的是称为URB的USB请求块。
如图20.4所示,在这棵树里,我们把树根比作主机控制器,树叶比作具体的USB设备,树干和树枝就是USB总线。树叶本身与树枝通过usb_driver连接,而树叶本身的驱动(读写、控制)则需要通过其树叶设备本身所属类设备驱动来完成。树根和树叶之间的"通信"依靠在树干和树枝里"流淌"的URB来完成。
由此可见,usb_driver本身只是起到了找到USB设备、管理USB设备连接和断开的作用,也就是说,它是公司入口处的"打卡机",可以获得员工(USB设备)的上/下班情况。树叶和员工一样,可以是研发工程师也可以是销售工程师,而作为USB设备的树叶可以是字符树叶、网络树叶或块树叶,因此必须实现相应设备类的驱动