基础概念之(1) --- 设备、配置、接口、端点

在USB设备的逻辑组织中,包含设备、配置、接口和端点4个层次。

配置:每个USB设备都提供了不同级别的配置信息,可以包含一个或多个配置,不同的配置使设备表现出不同的功能组合(在探测/连接期间需从其中选定一个),配置由多个接口组成。

接口:在USB协议中,接口由多个端点组成,代表一个基本的功能,是USB设备驱动程序控制的对象,一个功能复杂的USB设备可以具有多个接口。每个配置中可以有多个接口,而设备接口是端点的汇集(collection)。例如USB扬声器可以包含一个音频接口以及对旋钮和按钮的接口。一个配置中的所有接口可以同时有效,并可被不同的驱动程序连接。每个接口可以有备用接口,以提供不同质量的服务参数。在逻辑上,一个USB设备的功能划分是通过接口来完成的。比如说一个USB扬声器,可能会包括有两个接口:一个用于键盘控制,另外一个用于音频流传输。而事实上,这种设备需要用到不同的两个驱动程序来操作,一个控制键盘,一个控制音频流。

Linux上,接口使用struct usb_interface来描述,以下是该结构体中比较重要的字段:
struct usb_host_interface *altsetting(注意不是usb_interface
       其实据我理解,他应该是每个接口的设置,虽然名字上有点奇怪。该字段是一个设置的数组(一个接口可以有多个设置),每个usb_host_interface都包含一套由struct usb_host_endpoint定义的端点配置。但这些配置次序是不定的。
unsigned num_altstting
       可选设置的数量,即altsetting所指数组的元素个数。
struct usb_host_interface *cur_altsetting
       当前活动的设置,指向altsetting数组中的一个。此结构里面有一个usb_interface_descriptor叫做desc的成员,他应该是用于描述该interface的一些属性,其中bNumEndpoints是一个8位(b for byte)的数字,他代表了该接口的端点数。probe然后遍历所有的端点,检查他们的类型跟方向,注册到usb_skel中。
int minor
       当捆绑到该接口的USB驱动程序使用USB主设备号时,USB core分配的次设备号。仅在成功调用usb_register_dev之后才有效。    

端点:是USB通信的最基本形式,每一个USB设备接口在主机看来就是一个端点的集合。主机只能通过端点与设备进行通信,以使用设备的功能。在USB系统中每一个端点都有惟一的地址,这是由设备地址和端点号给出的。每个端点都有一定的属性,其中包括传输方式、总线访问频率、带宽、端点号和数据包的最大容量等。一个USB端点只能在一个方向承载数据,或者从主机到设备(称为输出端点),或者从设备到主机(称为输入端点),因此端点可看作一个单向的管道。

端点可分为如下4种类型:

控制(control 用于配置设备、获取设备信息、发送命令或者获取设备的状态报告;
中断(interrupt         USB 宿主要求设备传输数据时,中断端点会以一个固定的速率传送少量数据,还用于发送数据到 USB 设备以控制设备,一般不用于传送大量数据;
批量(bulk 用于大量数据的可靠传输,如果总线上的空间不足以发送整个批量包,它会被分割成多个包传输;
等时(isochronous 大量数据的不可靠传输,不保证数据的到达,但保证恒定的数据流,多用于数据采集;
端点0通常为控制端点,用于设备初始化参数等。只要设备连接到USB上并且上电端点0就可以被访问。端点1、2等一般用作数据端点,存放主机与设备间往来的数据。
 Linux中用struct usb_host_endpoint来描述USB端点,每个usb_host_endpoint中包含一个struct usb_endpoint_descriptor结构体,当中包含该端点的信息以及设备自定义的各种信息,这些信息包括:
bEndpointAddressb for byte
8 位端点地址,其地址还隐藏了端点方向的信息(之前说过,端点是单向的),可以用掩码 USB_DIR_OUT USB_DIR_IN 来确定。
bmAttributes
端点的类型,结合 USB_ENDPOINT_XFERTYPE_MASK 可以确定端点是 USB_ENDPOINT_XFER_ISOC (等时)、 USB_ENDPOINT_XFER_BULK (批量)还是 USB_ENDPOINT_XFER_INT (中断)。
wMaxPacketSize
端点一次处理的最大字节数。发送的 BULK 包可以大于这个数值,但会被分割传送。
bInterval
如果端点是中断类型,该值是端点的间隔设置,以毫秒为单位。

总体而言,USB设备非常复杂,由许多不同的逻辑单元组成,如图20.2所示,这些单元之间的关系如下:

图20.2 USB设备、配置、接口和端点



设备描述符:关于设备的通用信息,如供应商ID、产品ID和修订ID,支持的设备类、子类和适用的协议以及默认端点的最大包大小等。在Linux内核中,USB设备用usb_device结构体来描述,USB设备描述符定义为usb_device_descriptor结构体,如代码清单20.1所示。

代码清单20.1  usb_device_descriptor结构体

1  struct usb_device_descriptor 
2  {
3  _ _u8  bLength; //描述符长度
4  _ _u8  bDescriptorType; //描述符类型编号
5  
6  _ _le16 bcdUSB; //USB版本号
7  _ _u8  bDeviceClass; //USB分配的设备类code
8  _ _u8  bDeviceSubClass;// USB分配的子类code
9  _ _u8  bDeviceProtocol; //USB分配的协议code
10 _ _u8  bMaxPacketSize0; //endpoint0最大包大小
11 _ _le16 idVendor; //厂商编号
12 _ _le16 idProduct; //产品编号
13 _ _le16 bcdDevice; //设备出厂编号
14 _ _u8  iManufacturer; //描述厂商字符串的索引
15 _ _u8  iProduct; //描述产品字符串的索引
16 _ _u8  iSerialNumber; //描述设备序列号字符串的索引
17 _ _u8  bNumConfigurations; //可能的配置数量
18 } _ _attribute_ _ ((packed));

配置描述符:此配置中的接口数、支持的挂起和恢复能力以及功率要求。USB配置在内核中使用usb_host_config结构体描述,USB配置描述符定义为结构体usb_config_descriptor,如代码清单20.2所示。

代码清单20.2  usb_config_descriptor结构体

1  struct usb_config_descriptor 
2  {
3  _ _u8  bLength; //描述符长度
4  _ _u8  bDescriptorType; //描述符类型编号
5  
6  _ _le16 wTotalLength; //配置所返回的所有数据的大小
7  _ _u8  bNumInterfaces; // 配置所支持的接口数
8  _ _u8  bConfigurationValue; //Set_Configuration命令需要的参数值
9  _ _u8  iConfiguration; //描述该配置的字符串的索引值
10 _ _u8  bmAttributes; //供电模式的选择
11 _ _u8  bMaxPower; //设备从总线提取的最大电流
12 } _ _attribute_ _ ((packed));

接口描述符:接口类、子类和适用的协议,接口备用配置的数目和端点数目。USB接口在内核中使用usb_interface结构体描述,USB接口描述符定义为结构体usb_interface_descriptor,如代码清单20.3所示。

代码清单20.3  usb_interface_descriptor结构体

1  struct usb_interface_descriptor 
2  {
3  _ _u8  bLength;           //描述符长度
4  _ _u8  bDescriptorType; //描述符类型
5  
6  _ _u8  bInterfaceNumber;   // 接口的编号
7  _ _u8  bAlternateSetting; //备用的接口描述符编号
8  _ _u8  bNumEndpoints;      //该接口使用的端点数,不包括端点0
9  _ _u8  bInterfaceClass;    //接口类型
10 _ _u8  bInterfaceSubClass; //接口子类型
11 _ _u8  bInterfaceProtocol; //接口所遵循的协议
12 _ _u8  iInterface; //描述该接口的字符串索引值
13 } _ _attribute_ _ ((packed));

端点描述符:端点地址、方向和类型,支持的最大包大小,如果是中断类型的端点则还包括轮询频率。在Linux内核中,USB端点使用usb_host_endpoint结构体来描述,USB端点描述符定义为usb_endpoint_descriptor结构体,如代码清单20.4所示。

代码清单20.4  usb_endpoint_descriptor结构体

1  struct usb_endpoint_descriptor 
2  {
3  _ _u8  bLength; //描述符长度
4  _ _u8  bDescriptorType; //描述符类型
5 _ _u8  bEndpointAddress; //端点地址:0~3位是端点号,第7位是方向(0-OUT,1-IN)
6 _ _u8  bmAttributes; //端点属性:bit[0:1] 的值为00表示控制,为01表示同步,为02表示批量,为03表示中断
7  _ _le16 wMaxPacketSize;  本端点接收或发送的最大信息包的大小
8  _ _u8  bInterval;//轮询数据传送端点的时间间隔
9                       //对于批量传送的端点以及控制传送的端点,此域忽略
10                     //对于同步传送的端点,此域必须为1
11                     //对于中断传送的端点,此域值的范围为1~255
12 _ _u8  bRefresh;
13 _ _u8  bSynchAddress;
14 } _ _attribute_ _ ((packed));

字符串描述符:在其他描述符中会为某些字段提供字符串索引,它们可被用来检索描述性字符串,可以以多种语言形式提供。字符串描述符是可选的,有的设备有,有的设备没有,字符串描述符对应于usb_string_descriptor结构体,如代码清单20.5所示。

代码清单20.5  usb_string_descriptor结构体

1 struct usb_string_descriptor 
2 {
3 _ _u8  bLength; //描述符长度
4 _ _u8  bDescriptorType; //描述符类型
5 
6 _ _le16 wData[1];/* 以UTF-16LE编码 */
7 } _ _attribute_ _ ((packed));

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值