努力成为linux kernel hacker的人李万鹏原创作品,转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/04/25/6362603.aspx

这个是USB系统的拓扑图,4个部分构成:USB主机控制器,根集线器,集线器,设备。其中Root HubUSB主机控制器是绑定在一起的。

LINUX内核USB子系统学习笔记之初识USB

再了解一下USB驱动框架:

LINUX内核USB子系统学习笔记之初识USB

USB通信都是由host端发起的。USB设备驱动程序分配并初始化一个URB发给USB Core,USB Core改一改,发给USB主机控制器驱动,USB主机控制器驱动把它解析成包,在总线上进行传送。USB Core是由内核实现的,其实也就是把host control driver里的功能更集中的向上抽象了一层,它是用来对最上层的USB设备驱动屏蔽掉host control的不同。

USB设备的构成包括了配置,接口和端点。

LINUX内核USB子系统学习笔记之初识USB

1. 设备通常具有一个或者更多个配置

2. 配置经常具有一个或者更多个接口

3. 接口通常具有一个或者更多个设置

4. 接口没有或者具有一个以上的端点

需要注意的是,驱动是绑定到USB接口上,而不是整个设备。

USB通信最基本的形式是通过一个名为端点(endpoint)的东西。它是真实存在的。端点只能往一个方向传送数据(端点0除外,端点0使用message管道,它既可以IN又可以OUT),或者IN,或者OUT。除了端点0,低速设备只能有2个端点,高速设备也只能有15IN端点和15OUT端点。主机和端点之间的数据传输是通过管道。端点只有在device上才有,协议说端点代表在主机和设备端点之间移动数据的能力。

LINUX内核USB子系统学习笔记之初识USB

端点有4中不同的类型:控制,批量,等时,中断。

对应USB4种不同的传输类型:

1. 控制传输:适用于小量的,对传输时间和速率没有要求的设备。如USB设备配置信息。

2. 批量传输:适用于类似打印机,扫描仪等传输量大,但对传输时间和速度无要求的设备。

3. 等时传输:适用于大量的,速率恒定,具有周期性的数据,对实时性有要求的,比如音视频。

4. 中断传输:适用于非大量,但具有周期性的数据,比如鼠标键盘。

4大类由4transaction组成:

1. IN transaction

IN事务为host输入服务,当host需要从设备获得数据的时候,就需要IN事务。

2. OUT transaction

OUT事务为host输出服务,当host需要输出数据到设备的时候,就需要OUT事务。

3. SETUP transaction

SETUP事务为host控制服务,当host希望传输一些USB规范的默认操作的时候就需要使用setup事务。

4. SOF transaction

这个用于帧同步。

然后这4transaction又由3类包组成,每类又分几种:

LINUX内核USB子系统学习笔记之初识USB

1. in

in包用于指明当前的事务为in类型的。

2. out

out包用于指明当前事务为out类型的。

3. setup

setup包指明当前事务为setup类型的。

4. sof

sof包指明当前事务为setup类型的。

LINUX内核USB子系统学习笔记之初识USB

1. data0

该数据包的类型为0

2. data1

该数据包的类型为1

LINUX内核USB子系统学习笔记之初识USB

1. ack

ack握手包指明当前的事务的数据包传输是成功的。

2. nak

nak握手包指明当前设备忙,不能处理数据包,请主机稍后再次发送。

3. stall

stall握手包指明当前设备不能接受或者传输数据,表示一个严重的错误。

下图是一个USB鼠标插入Linux系统时完整的枚举过程,一共发生了11次传输,每次传输包括几个事务,每个事务又包括几个包,每个包包括几个域。

LINUX内核USB子系统学习笔记之初识USB

LINUX内核USB子系统学习笔记之初识USB

这里有一个概念需要注意,这里的中断传输与硬件中断那个中断是不一样的,这个中断传输实际是靠USB host control轮询usb device来实现的,而USB host control对于CPU则是基于中断的机制。拿USB鼠标为例,USB host controlUSB鼠标不断请求,这个请求的间隔是很短的,在USB spec Table 9-13端点描述符中的bInterval域中指定的,当鼠标发生过了事件之后,鼠标会发送数据回host,这时USB host control中断通知CPU,于是usb_mouse_irq被调用,在usb_mouse_irq里,就可以读取鼠标发回来的数据,当读完之后,驱动再次调用usb_submit_urb发出请求,就这么一直重复下去,一个usb鼠标的驱动也就完成了。下面是USB鼠标中断传输图,可以看到USB host controlusb device发送了IN包,没有数据的时候device回复的是NAK,有数据的时候才向host control发送DATA包。

LINUX内核USB子系统学习笔记之初识USB

相关文章: