回顾一下USB的相关知识
USB(Universal Serial Bus)总线又叫通用串行外部总线,它是20世纪90年代发展起来的。USB接口现在得到了广泛的应用和普及,现在的PC机中都带有大量的USB接口。它最大的特点就是方便通用、支持热插拔并且可以在一个接口上插上多个设备。当设备用电量小的时候,它还可以充当电源。它的众多优点使得它得到了广泛的应用。
在PC机器内部有个USB中央控制器,这个中央控制器负责管理插到USB接口上的设备。当主机要向设备发送或接受数据时,都是向USB中央控制器发出命令,USB设备不具备主动与主机通信的能力。编写USB设备驱动不用考虑申请设备地址空间,因为USB中央控制器会给设备分配一个设备号,这个设备号就代表这个设备。
USB设备和USB中央控制器之间的通信是通过端点来完成的。端点的职能有点类似一栋大楼的传达室。例如每个楼层都有一个传达室,当要访问5楼的10号房间时,那就是向5号端点发起对话,并提供偏移量,也就10号房间。USB接口的端点按传输信息的类型分为以下4种:
a -- 控制端点
主要用来传输控制信息的,例如配置设备时发出的控制信息。控制端点一般都是双向,既可以输入又可以输出。其他端点的输出方向一般是单向的,要么是输入,要么是输出的。这里是站在主机的角度来谈论输入输出的。
b -- 中断端点
主要用来传输中断信息的,由于USB设备是受USB中央控制器管理的,因此USB设备没有向主机发出中断的能力,并且USB设备不能主动向主机发出请求,只有主机可以向USB设备发出命令请求,因此所谓的中断是指主机周期性的查询USB设备。
c -- 批量端点
主要用来传输批量信息的,批量信息就意味着大量的信息。U盘一般主要使用的就是批量端点。本文研究的USB无线网卡也是使用批量断点来传输数据的。发送和接收函数都是使用批量端点和USB设备传输数据的。
b -- 等时端点
主要用来传输等时信息的,主要用于传输实时性要求较高的信息,例如实时的音频、视频等信息。有代表性的USB设备是USB摄像头等。
在一个具体的USB设备中不要求一定都存在这4种类型的端点,例如U盘一般就只有批量端点和控制端点。在Linux内核中用来描述USB设备端点信息的数据结构如下:
struct usb_endpoint_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
__u8 bRefresh;
_u8 bSynchAddress;
} __attribute__ ((packed));
成员bLength描述本数据结构共有多少字节,因为后两个成员是针对音频设备的,如果不是音频设备则可以没有后两个成员。成员bDescriptorType是描述本数据结构要描述的类型,这里是描述端点的,在内核中0x05就代表端点。
成员bEndpointAddress包含端点号和输出方向,bits0-bits3表示的是端点号,从这里可以看出一个USB设备最多只能有不超过16个端点,bits8是代表传输方向的,如果该位是1就代表输入,也就是读设备;如果该位为0就代表输出,也就是写设备。
成员bmAttributes 表示该端点的类型,如上述的4种类型。
成员wMaxPacketSize表示该端点一次可以传输的最多字节数。如果要传输的数据大于这个数字,那就要分多次传输。成员bInterval代表的是该端点希望主机轮询自己的时间间隔,这只是一种希望,具体还要看主机怎么做。
该数据结构最后的__att