linux设备驱动(25)usb驱动-基础知识

在终端用户看来,USB设备为主机提供了多种多样的附加功能,如文件传输,声音播放等,但对USB主机来说,它与所有USB设备的接口都是一致的。一个USB设备由3个功能模块组成:USB总线接口、USB逻辑设备和功能单元:
(1)USB总线接口指的是USB设备中的串行接口引擎(SIE);
(2)USB逻辑设备被USB系统软件看作是一个端点的集合;
(3)功能单元被客户软件看作是一个接口的集合。SIE、端点和接口都是USB设备的组成单元;

1 usb总线驱动的作用

(1)识别USB设备,给USB设备找到对应的驱动程序

(2)新接入的USB设备的默认地址(编号)是0,在未分配新编号前,PC主机使用0地址和它通信。然后USB总线驱动程序都会给它分配一个地址(编号)

(3)主机想访问USB总线上某个USB设备时,发出的命令都含有对应的地址(编号)

(4)USB是一种主从结构。主机叫做Host,从机叫做Device,所有的USB传输,都是从USB主机这方发起;USB设备没有"主动"通知USB主机的能力。例如:USB鼠标滑动一下立刻产生数据,但是它没有能力通知PC机来读数据,只能被动地等得主机来读。

2 usb的传输类型

USB 通讯的最基本形式是通过端点。一个USB端点只能向一个方向传输数据(从主机到设备(称为输出端点)或者从设备到主机(称为输入端点))。端点可被看作一个单向的管道。USB 端点有 4 种不同类型, 分别具有不同的数据传送方式:

(1)控制传输(control) 

是每一个USB设备必须支持的,通常用来获取设备描述符、设置设备的状态等等。一个USB设备从插入到最后的拔出这个过程一定会产生控制传输,即便这个USB设备不能被这个系统支持。

(2)中断传输(interrupt)

支持中断传输的典型设备有USB鼠标、 USB键盘等等。中断传输不是说我的设备真正发出一个中断,然后主机会来读取数据。它其实是一种轮询的方式来完成数据的通信。USB设备会在设备驱动程序中设置一个参数叫做interval,它是endpoint的一个成员。 interval是间隔时间的意思,表示我这个设备希望主机多长时间来轮询自己,只要这个值确定了之后,我主机就会周期性的来查看有没有数据需要处理

(3)批量传输(bulk)

支持批量传输最典型的设备就是U盘,它进行大数量的数据传输,能够保证数据的准确性,但是时间不是固定的。

(4)实时传输(isochronous)

USB摄像头就是实时传输设备的典型代表,它同样进行大数量的数据传输,数据的准确性无法保证,但是对传输延迟非常敏感,也就是说对实时性要求比较高

3 USB端点

USB设备与主机会有若干个通信的”端点”,每个端点都有个端点号,除了端点0外,每一个端点只能工作在一种传输类型(控制传输、中断传输、批量传输、实时传输)下,一个传输方向下。传输方向都是基于USB主机的立场说的,比如:鼠标的数据是从鼠标传到PC机, 对应的端点称为"中断输入端点"。其中端点0是设备的默认控制端点, 既能输出也能输入,用于USB设备的识别过程。

4 usb描述符

为了更好地描述USB设备的特征,USB提出了设备架构的概念。从这个角度来看,可以认为USB设备是由一些配置、接口和端点组成,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。其中,配置和接口是对USB设备功能的抽象,实际的数据传输由端点来完成。在使用USB设备前,必须指明其采用的配置和接口。这个步骤一般是在设备接入主机时设备进行枚举时完成的。

设备通常有一个或多个配置;配置通常有一个或多个接口;接口通常有一个或多个设置;接口有零或多个端点。如下图所示:

4.1 设备描述符

定义位于:include\uapi\linux\usb\ch9.h

设备代表一个USB设备,它由一个或多个配置组成。设备描述符用于说明设备的总体信息,并指明其所含的配置的个数。一个USB设备只能有一个设备描述符。USB设备描述符位于USB设备结构体usb_device中的成员descriptor中。同样地,配置、接口、端点描述符也是位于USB配置、接口、端点结构体中,不过这3个对于我们写驱动的不是很常用。

 1 /* USB_DT_DEVICE: Device descriptor */
 2 struct usb_device_descriptor {
 3  __u8  bLength;                          //本描述符的size
 4  __u8  bDescriptorType;              //描述符的类型,这里是设备描述符DEVICE
 5  __u16 bcdUSB;                           //指明usb的版本,比如usb2.0
 6  __u8  bDeviceClass;                 //
 7  __u8  bDeviceSubClass;             //子类
 8  __u8  bDeviceProtocol;              //指定协议
 9  __u8  bMaxPacketSize0;            //端点0对应的最大包大小
10  __u16 idVendor;                         //厂家ID
11  __u16 idProduct;                        //产品ID
12  __u16 bcdDevice;                       //设备的发布号
13  __u8  iManufacturer;                 //字符串描述符中厂家ID的索引
14  __u8  iProduct;                         //字符串描述符中产品ID的索引
15  __u8  iSerialNumber;                 //字符串描述符中设备序列号的索引
16  __u8  bNumConfigurations;              //配置描述符的个数,表示有多少个配置描述符
17 } __attribute__ ((packed));

4.2 配置描述符

       一个USB设备可以包含一个或多个配置,如USB设备的低功耗模式和高功耗模式可分别对应一个配置。在使用USB设备前,必须为其选择一个合适的配置。配置描述符用于说明USB设备中各个配置的特性,如配置所含接口的个数等。USB设备的每一个配置都必须有一个配置描述符。

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

4.3 接口描述符

      一个配置可以包含一个或多个接口,例如对一个光驱来说,当用于文件传输时,使用其大容量存储接口;而当用于播放CD时,使用其音频接口。接口是端点的集合,可以包含一个或多个可替换设置,用户能够在USB处于配置状态时改变当前接口所含的个数和特性。接口描述符用于说明设备中各个接口的特性,如接口所属的设备类及其子类等。USB设备的每个接口都必须有一个接口描述符。

它位于usb_interface->cur_altsetting->desc 这个成员结构体里

 1 struct usb_interface_descriptor {  
 2   __u8  bLength;                          //描述符的长度
 3   __u8  bDescriptorType;              //描述符类型的编号
 4 
 5   __u8  bInterfaceNumber;           //接口的编号
 6   __u8  bAlternateSetting;            //备用的接口描述符编号,提供不同质量的服务参数.
 7   __u8  bNumEndpoints;              //要使用的端点个数(不包括端点0), 表示有多少个端点描述符,比如鼠标就只有一个端点
 8   __u8  bInterfaceClass;              //接口类型,与驱动的id_table 
 9   __u8  bInterfaceSubClass;                 //接口子类型
10   __u8  bInterfaceProtocol;                 //接口所遵循的协议
11   __u8  iInterface;                        //描述该接口的字符串索引值
12  } __attribute__ ((packed)

4.4  端点描述符

      端点是USB设备中的实际物理单元,USB数据传输就是在主机和USB设备各个端点之间进行的。端点一般由USB接口芯片提供,例如Freescale公司的MC68HC908JB8和MC9S12UF32。USB设备中的每一个端点都有唯一的端点号,每个端点所支持的数据传输方向一般而言也是确定的:或是输入(IN),或是输出(OUT)。也有些芯片提供的端点的数据方向是可以配置的,例如MC68HC908JB8包含有两个用于数据收发的端点:端点1和端点2。其中端点1只能用于数据发送,即支持输入(IN)操作;端点2既能用于数据发送,也可用于数据接收,即支持输入(IN)和输出(OUT)操作。而MC9S12UF32具有6个端点。

     利用设备地址、端点号和传输方向就可以指定一个端点,并与它进行通信。端点的传输特性还决定了其与主机通信是所采用的传输类型,例如控制端点只能使用控制传输。根据端点的不同用途,可将端点分为两类:0号端点和非0号端点。

      0号端点比较特殊,它有数据输入IN和数据输出OUT两个物理单元,且只能支持控制传输。所有的USB设备都必须含有一个0号端点,用作默认控制管道。USB系统软件就是使用该管道与USB逻辑设备进行配置通信的。0号端点在USB设备上的以后就可以使用,而非0号端点必须要在配置以后才可以使用。

     根据具体应用的需要,USB设备还可以含有多个除0号端点以外的其他端点。对于低速设备,其附加的端点数最多为2个;对于全速/高速设备,其附加的端点数最多为15个。

 1 struct usb_endpoint_descriptor {
 2 __u8  bLength;                          //描述符的长度
 3 __u8  bDescriptorType;              //描述符类型的编号
 4 
 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;                     //间隔时间,用在中断传输上,比如间隔时间查询鼠标的数据。轮询数据传送端点的时间间隔;对于批量传送的端点以及控制传送的端点,此域忽略;对于同步传送的端点,此域必须为1.
 9 
10  
11 /* NOTE:  these two are _only_ in audio endpoints. */
12 /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
13 __u8  bRefresh;
14 __u8  bSynchAddress;
15 
16 } __attribute__ ((packed));

参考博文:https://blog.csdn.net/zqixiao_09/java/article/details/50984074

https://www.cnblogs.com/lifexy/p/7634511.html

posted @ 2020-07-07 23:04  Action_er  阅读(529)  评论(0编辑  收藏  举报