USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配。
USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动,通常,对于USB这种标准化的设备,内核已经将主机控制器的驱动编写好了,设备上的Gadget驱动通常只运行固件程序而不是基于Linux, 所以驱动工程师的主要工作就是编写主机端的USB设备驱动。
USB子系统框架
下图表示了Linux中USB子系统的框架结构,和i2c一样,USB子系统也可分为三层:**设备驱动层--USB核心--控制器驱动层*
作为热插拔总线, USB和非热插拔总线最大的区别就是总线无法事前获知设备的信息以及设备何时被插入或拔出,所以也就不能使用任意一种形式将设备信息事前写入内核。
为了解决由于热插拔引起的设备识别问题,USB总线通过枚举的方式来获取一个接入总线的USB设备的设备信息——一个由device->config->interface->endpoint逐级描述的设备,基于分离的思想,USB子系统中设计了一组结构来描述这几个维度的设备信息,相比之下,i2c总线只要一个i2c_client即可描述一个设备.
USB总线上的所有通信都是由主机发起的,所以本质上,USB都是采用轮询的方式进行的。USB总线会使用轮询的方式不断检测总线上是否有设备接入,如果有设备接入相应的D+D-就会有电平变化。然后总线就会按照USB规定的协议与设备进行通信,设备将存储在自身的设备信息依次交给主机,主机将这些信息按照4层模型组织起来。上报到内核,内核中的USB子系统再去匹配相应的驱动,USB设备驱动是面向interface这一层次的信息的
作为一种高度标准化的设备, 虽然USB本身十分复杂, 但是内核已经为我们完成了相当多的工作, 下述的常用设备驱动在内核中已经实现了。很多时候, 驱动的难度不是看设备的复杂程度, 而是看标准化程度
音频设备类
通信设备类
HID设备类
显示设备类
海量存储设备类
电源设备类
打印设备类
集线器设备类
核心结构和方法简述
核心结构
基于分离的思想,USB子系统也提供了描述一个USB设备的结构,只不过基于USB协议,完整描述一个USB设备信息需要9个结构,这些结构中,前4个用来描述一个USB设备的硬件信息,即设备本身的信息,这些信息是写入到设备的eeprom的,在任何USB主机中看到的都一样,这些信息可以使用lsusb -v命令来查看; 后5个描述一个USB设备的软件信息,即除了硬件信息之外,Linux为了管理一个USB设备还要封装一些信息,是OS-specific的信息; USB设备硬件信息和软件信息的关系类似于中断子系统中的硬件中断和内核中断,只不过更复杂一点。