仅为个人理解,错误之处,欢迎指正。
硬件方面:
USB接口,四根线,电源、地加差分D+ D-
采用差分线可以提高数据可靠性和速率
其实,对于驱动开发来讲,硬件方面了解这么多就可以了。
但是,接触USB的人,大多还是认为USB是比较复杂的。这种复杂性来自于逻辑层面。为了进一步展开,再补充硬件方面的一些内容:
其一,USB是串行总线,但计算机处理的数据都是以字节为基本单位的,虽然不一定算严格的并行吧,但是在物理层面,也就是接近硬件最底层,数据还是通过串并转换后,再在前面所述的差分线上传输。发送是并转串,接收是串转并来恢复。
总的来讲,可以理解底层物理连接就是一个可靠通道。至于这个通道上传输什么,那就是USB协议的东西了。就像内存只是存储指令和数据,这些指令和数据通过组合可表达的逻辑意义就多了去了。
其二,就是芯片本身根据USB设备用途(大容量存储、键盘、鼠标、显示、网络、打印等)实现了部分功能。基于芯片的命令、状态、数据寄存器可完成USB协议的适配,并最终完成数据的传输。这里所说的实现部分功能,包括前述物理信号层面。
剩下的都可以围绕软件展开。
软件方面:
硬件层面为软件打了基础,提供数据传输的通道,软件就要考虑如何组织数据,进一步的考虑如何符合USB协议。
针对USB,需要了解如下一些概念:
(1)USB设备分主机控制器和设备,分别承担主从功能。一般由主机控制器控制总线的使用。
(2)USB设备的连接扩展,通过集线器完成。主机控制器引出根HUB,根HUB上可以接USB设备或者USB HUB,但是USB设备之间不能直接连接。
(3)设备信息可通过设备描述符获取。
(4)设备信息可通过配置描述符配置。
(5)配置描述符中可指定接口,每一个接口对应一个逻辑功能,接口由接口描述符描述。
(6)接口由一个或多个端点构成。通常默认都具备0号端点。0号端点又常为控制端点,USB主机控制器通过0号端点,获取设备接口信息和配置接口。
(7)USB主机控制器一般使用其他端点完成数据传输,比如输入和输出。
站在软件层面,可以这样理解:
(1)一个物理USB设备由多个逻辑设备构成,逻辑设备提供某一具体功能。
(2)逻辑设备通过接口描述,由端点构成。
(3)从软件角度来看,每一个端点跟主机控制器及其上软件形成一个逻辑的管道,管道内的数据是连续的有意义的。
(4)物理硬件连线上可能同时在传输多个管道的数据,但是通过特殊的格式,硬件和软件都可以区分当前传输的数据归属于那个管道。
(5)通道中传输的数据有多种类型,比如控制传输、同步传输、中断传输、批量传输等。
(6)通道中传输的数据被组织为IRP(IO请求分组),IRP由事务组成,不同的事务构成帧通过硬件传输。
举个例子,比如对于U盘来讲,硬件上包括USB设备控制器和存储FLASH。USB设备控制器负责处理USB协议相关内容,对驱动提供命令、状态、数据寄存器。
(1)当U盘插入电脑,上电后,USB设备中的固件对USB设备控制器进行配置,等待主机控制器的查询和配置。
(2)当U盘插入电脑后,电脑端主机控制器会检测到USB设备接入。按照USB规范,主机控制器跟U盘的0号端口(假定U盘只有一个接口)沟通。
(3)因为0号端口的数据格式、功能要求是规范定义的,所以通过0号端口,主机控制器就可以知道当前插入的是什么设备,支持哪些特性。
(4)接着,主机控制器通过与0号端口建立的通道,完成对设备的进一步配置和其他逻辑管道的建立,比如数据输入和数据输出两个管道。
(5)USB设备端的驱动负责配合主机控制器完成0号通道的交互,并建立其他通道。
(6)完成交互工作后,电脑端应该将该USB设备标识为一个U盘,并提供上层软件访问文件系统的途径。在这之前,U盘端的驱动需要提前将FLASH格式化为某一文件系统。
(7)当向U盘写数据时,写的数据和地址按照USB规范组织后由主机控制器通过写通道发送到U盘控制器,U盘驱动读取数据和地址后,将数据通过写FLASH命令(一般是先擦后写)写入特定块和扇区。
(8)当读取U盘数据时,主机控制器通过读通道发送读取地址,U盘驱动获取命令和地址后,读取FLASH特定区块数据,送给主机端。
上述过程中,对USB设备而言,驱动访问的命令、状态、数据寄存器都是为USB总线沟通服务的,数据按USB规范要求的打包、解包、事务、分组、帧等等都由硬件完成,驱动只是通过寄存器获取结果。
主机控制器端也是类似的。也就是说有些过程是硬件完成的,有些过程是驱动完成的,并且是通用的(比如PC识别U盘),有些过程是特定设备相关的,需要单独编写。
基于上述信息,再进一步了解USB裸机驱动(通过USB芯片手册),对规范和芯片的理解会更深。在裸机驱动基础上,再在Linux等操作系统的框架中了解USB驱动编写,就相对较为容易了。