1、USB驱动引入
USB(全称UniversalSerialBus,通用串行总线),早已成为PC及嵌入式设备中最常用、最方便的通讯插口。LinuxUSB子较为庞大,本文主要对Linux系统下的USB总线驱动框架进行概述,重点的细节待后续文章展开。
首先来看一个现象,插入USB设备后linux系统复印如下日志:
拔出后提示:usb1-1:USBdisconnect,address2
1.1USB的硬件结构
如图网桥(USBRootHub)端两条数据线(D+D-),都接有15K的下拉阻值,当无设备接入时,网桥数据线D+D-的电流为低电平。当设备接入时,因为设备的数据线上接有1.5K上拉阻值,致使1根数据线被拉高。网桥按照数据线被拉高得悉有设备接入,并按照D+为高还是D-为高来判定所接入的设备是全速USB设备(D+为高)还是低速USB设备(D-为高)。
1.2USB接入辨识大致过程
当辨识出有USB设备插入后,linux内的USB总线驱动程序发出至该设备,与设备对话,并寻问设备信息(描述符),设备收到恳求后,回复设备描述符给总线驱动程序。且总线驱动程序会为该设备分配一个地址linux驱动程序开发视频,如上地址为2,当后期访问某个USB设备时,均会通过这个地址编号,当新接入的USB设备被第一次访问时,以地址0来访问。当USB总线驱动程序辨识出设备后,会为其找到该USB设备驱动程序,如鼠标,键盘,U盘。
USB通讯过程均为主从结构,USB主机发起通讯恳求,设备进行数据回复,USB设备不具备主动向主机通讯的能力。
2、USB总线驱动框架
如上,我们大致了解了USB的简单通讯过程,这么哪些是USB总线驱动程序?哪些是USB设备驱动呢?
2.1USB的总线驱动框架
USB总线框架总结为如右图:
2.2USBCore
USBCore这个模块是纯软件部份,并不代表一个设备,是独立于硬件的合同栈,它是所有USB设备赖以生存的模块,即USB子系统的核心。代码坐落kernel/drivers/usb/core目录下。
USBCore为设备驱动程序提供服务,提供一个用于访问和控制USB硬件的插口,而不用考虑系统当前使用的哪种HOSTController。USBCore将用户的恳求映射到相关的HCD,用户不能直接访问HCD。USBCore就是HCD与USB设备的桥梁。
其Makefile为:
USB的初始化函数在kernel/drivers/usb/core/usb.c中定义,主要完成bus_register(USB总线注册)、usb_major_init(注册usb主控器字符设备)、usb_register(注册usbfs驱动)、usb_hub_init(USBHub初始化,注册hub驱动、创建内核守护线程来检测hub端口的状态变化)等工作linux apache 虚拟主机,后续具体剖析。
2.3USBHCD(HostControllerDriver)
硬件主机控制器HostController之上运行的是HCD,是对主机控制器硬件的一个具象,实现核心层与控制器之间的对话插口,USBHCD包含多种USB插口规范:
(1)UHCI:Intel提供,通用主机控制插口,USB1.0/1.1;
(2)OHCI:谷歌提供,开放主机控制插口,USB1.0/1.1;
(3)EHCI:提高主机控制插口,USB2.0;
2.4USBDeviceDriverUSB设备驱动框架如右图所示:
USB设备是由一些配置(configuration)、接口(interface)和端点(endpoint)组成,,即一个USB设备可以富含一个或多个配置,在每位配置中可富含一个或多个插口,在每位插口中可富含若干个端点。一个USB设备驱动可能包含多个子驱动。一个USB设备子驱动程序对应一个USB插口,而非整个USB设备。
USB设备使用各类描述符来说明其设备构架,包括设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符。前面单独讨论USB设备描述符。
USB传输的对象为端点(endpoint),每一个端点都有传输类型,传输方向,不仅端点0外,每一个端点只支持一个方向的数据传输,端点0用于控制传输,既能输出也能输入。输入(IN)、输出(OUT)"都是"基于USB主机的立场说的。例如键盘的数据是从键盘传到PC机,对应的端点称为"输入端点"。
USB的传输类型:
a.控制传输:可靠linux c,时间有保证,例如:USB设备的辨识过程
b.批量传输:可靠,时间没有保证,例如:U盘
c.中断传输:可靠,实时,例如:USB键盘
d.实时传输:不可靠,实时,例如:USB摄像头
针对不同类型的USB设备,须要实现特定的USB驱动程序。如HID(HumanInterfaceDevice),属于人机交互类的设备,如USB键盘linux驱动程序开发视频,USB鼠标等。该类设备必须遵守HID设计规范。
在Linux内核中,使用structusb_driver结构体来描述一个USB驱动,通过usb_register在USB驱动中注册进内核。
因而USB设备驱动开发,主要包含如下两个部份:
分配/设置usb_driver结构体,实现并填充结构体内容
注册usb_driver
后续将对USB键盘驱动进行详尽剖析,其代码在kernel/drivers/hid/usbhid/usbmouse.c
3、USB设备辨识过程
通过以上剖析,USB设备驱动模型可以概括为如右图。
主要包含三个部份:USB控制器驱动,USB核心,USB设备驱动。如上图khubd是USB守护进程,当USB设备插入的时侯,守护进程检测到,USB主机控制器都会形成一个hub_irq中断,控制器调用hub的侦测函数,来解析设备信息。
下边剖析一下USB设备的辨识过程。
以上显示了设备插入到USB设备驱动被调用的函数流程,前面将掏出一章具体剖析函数内部实现来进一步剖析USB设备辨识中做了什么事情。
4、总结
通过以上内容,我们从整体上认识了USB硬件辨识过程,USB总线框架及USB设备驱动框架。后续会针对一些重点知识进行专题剖析。主要包括:
USB设备描述符解析
USB四类传输类型
USB数据包格式剖析
USB键盘设备驱动代码剖析
USB初始化代码剖析
USB枚举过程代码剖析
本文原创地址://q13zd.cn/lzxqdkjukjzj.html编辑:刘遄,审核员:暂无