USB设备驱动
在Linux 内核中,使用usb_driver 结构体描述一个USB 设备驱动,usb_driver 结构体的定义如代码清单20.11 所示。
代码清单20.11 usb_driver 结构体
struct usb_driver {
const char *name; /* 驱动名称 */
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id); /*探测函数*/
void (*disconnect) (struct usb_interface *intf); /*断开函数*/
int (*ioctl) (struct usb_interface *intf, unsigned int code,
void *buf); /* I/O 控制函数 */
int (*suspend) (struct usb_interface *intf, pm_message_t message);/*挂起函数*/
int (*resume) (struct usb_interface *intf); /* 恢复函数 */
int (*reset_resume)(struct usb_interface *intf);
void (*pre_reset) (struct usb_interface *intf);
void (*post_reset) (struct usb_interface *intf);
const struct usb_device_id *id_table;/* usb_device_id 表指针 */
struct usb_dynids dynids;
struct usbdrv_wrap drvwrap;
unsigned int no_dynamic_id:1;
unsigned int supports_autosuspend:1;
unsigned int soft_unbind:1;
};
在编写新的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_flags(标明要与哪些成员匹配,包含DEV_LO、DEV_HI、DEV_CLASS、DEV_SUBCLASS、DEV_PROTOCOL、INT_CLASS、INT_SUBCLASS、INT_PROTOCOL)。可以借助下面一组宏来生成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 结构体实例。
当USB 核心检测到某个设备的属性和某个驱动程序的usb_device_id 结构体所携带的信息一致时,这个驱动程序的probe()函数就被执行。拔掉设备或者卸掉驱动模块后,USB 核心就执行disconnect()函数来响应这个动作。
上述usb_driver 结构体中的函数是USB 设备驱动中USB 相关的部分,而USB 只是一个总线,真正的USB 设备驱动的主体工作仍然是USB 设备本身所属类型的驱动,如字符设备、tty 设备、块设备、输入设备等。因此USB 设备驱动包含其作为总线上挂在设备的驱动和本身所属设备类型的驱动两部分。
与platform_driver 类似,usb_driver 起到了“牵线”的作用,即在probe()里注册相应的字符、tty 等设备,在disconnect()注销相应的字符、tty 等设备,而原先对设备的注册和注销一般直接发生在模块加载和卸载函数中。
尽管USB 本身所属设备驱动的结构与其不挂在USB 总线上时完全相同,但是在访问方式上却发生了很大的变化,例如,对于USB 接口的字符设备而言,尽管仍然是write()、read()、ioctl()这些函数,但是在这些函数中,贯穿始终的是称为URB 的USB 请求块。
如图20.4 所示,在这棵树里,我们把树根比作主机控制器,树叶比作具体的USB 设备,树干和树枝就是USB 总线。树叶本身与树枝通过usb_driver 连接,而树叶本身的驱动(读写、控制)则需要通过其树叶设备本身所属类设备驱动来完成。树根和树叶之间的“通信”依靠在树干和树枝里“流淌”的URB 来完成。

由此可见,usb_driver 本身只是起到了找到USB 设备、管理USB 设备连接和断开的作用,也就是说,它是公司入口处的“打卡机”,可以获得员工(USB 设备)的上/下班情况。树叶和员工一样,可以是研发工程师也可以是销售工程师,而作为USB 设备的树叶可以是字符树叶、网络树叶或块树叶,因此必须实现相应设备类的驱动。
USB设备驱动的更多相关文章
- usb设备驱动描述,王明学learn
usb设备驱动 本章主要内容包含以下:USB总线介绍,USB协议分析,USB系统架构 一.USB总线介绍 1.1USB发展史 USB(Universal Serial Bus)通用串行总线,是一种外部 ...
- USB设备驱动概述
USB设备驱动 · )USB Hub:每个USBHost控制器都会自带一个USB Hub,被称为根(Root)Hub.这个根Hub可以接子(Sub)Hub,每个Hub上挂载USB设备.一般PC有8个 ...
- Linux下 USB设备驱动分析(原创)
之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...
- Linux下usb设备驱动详解
USB驱动分为两块,一块是USB的bus驱动,这个东西,Linux内核已经做好了,我们可以不管,我们只需要了解它的功能.形象的说,USB的bus驱动相当于铺出一条路来,让所有的信息都可以通过这条USB ...
- Linux USB驱动学习总结(二)---- USB设备驱动
USB 设备驱动: 一.USB 描述符:(存在于USB 的E2PROM里面) 1. 设备描述符:struct usb_device_descriptor 2. 配置描述符:struct usb_c ...
- 嵌入式Linux驱动学习之路(二十)USB设备驱动
USB在接入系统的时候,以0的设备ID和主机通信,然后由主机为其分配新的ID. 在主机端,D+和D-都是下拉接地的.而设备端的D-接上拉时,表明此设备为高速设备:12M/s. D+接上拉时则是全速设备 ...
- Linux usb子系统(二):USB设备驱动usb-skeleton.c
usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...
- USB2.0学习笔记连载(九):USB设备驱动的安装
在第一次插入USB设备时(笔者用的是自己做的USB最小系统来测试),插入电脑后,在设备管理器中会显示 未知设备,如下图所示: 点击右键,选择属性,在详细信息中可以看到硬件ID以及PID等,如下图所示. ...
- USB设备驱动_WDS
1. usb_alloc_dev中的 bus_type 中指定了匹配函数,和uevent中的环境参数. ====>不同的bus_type的匹配函数可能是不同的,uevent的环境变量参数也可能是 ...
随机推荐
- Arch-Linux-添加中文字体
代码下载: Arch-Linux-添加中文字体.txt
- python 实例属性之单,双下划线
具体区别看下面例子 class A: def __init__(self,name='Andy'): self._name = name class B: def __init__(self,name ...
- android下拉菜单 spinner 学习
首先看一下继承关系: public class Spinner extends AbsSpinner implements DialogInterface.OnClickListener Class ...
- C/C++笔试经典程序(二)
1.下面5个函数哪个能够成功进行两个数的交换? swap1传的是值的副本,在函数体内被修改了形参p.q(实际参数a.b的一个拷贝),p.q的值确实交换了,但是它们是局部变量,不会影响到主函数中的a和b ...
- Rational Functional Tester 对象文件(rftdef)合并
Rational Functional Tester (RFT) 是一款集成在Eclipse上的自动化测试工具.而自动化测试最麻烦的维护部分,一大部分也是指的是对象库文件的管理维护. 之前的项目里,经 ...
- 25_android下文件访问的权限
写文件:FileOutputStream fos = 上下文.openFileOutput("private.txt",Context.MODE_PRIVATR);参数1 文件名, ...
- Android各个文件夹对应的分辨率?
- 设置lable文本内容的行间距
NSMutableParagraphStyle *paragraphStyle =[ [NSMutableParagraphStyle alloc] init]; paragraphStyle.lin ...
- cordova ios --->OC 调用 js (一)
1.在HTML中定义一个函数如OCcallJS() function OCcallJS(){ alert("OC 调用js 的 方法"); } 2.当webview 加载完成的时候 ...
- OpenGL函数解析之glMatrixMode(GLenum mode)
函数原型:void glMatrixMode(GLenum mode) 函数说明:glMatrixMode函数只有一个枚举类型的参数mode,用来指定哪一个矩阵堆栈式下一个矩阵操作的目标. mode有 ...