本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50984074

在终端用户看来,USB设备为主机提供了多种多样的附加功能,如文件传输,声音播放等,但对USB主机来说,它与所有USB设备的接口都是一致的。一个USB设备由3个功能模块组成:USB总线接口USB逻辑设备功能单元:

a -- 这里的USB总线接口指的是USB设备中的串行接口引擎(SIE);

b -- USB逻辑设备被USB系统软件看作是一个端点的集合

c -- 功能单元被客户软件看作是一个接口的集合。SIE、端点和接口都是USB设备的组成单元;

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

这些单元之间的关系如下:

设备通常有一个或多个配置;

配置通常有一个或多个接口;

接口通常有一个或多个设置;

接口有零或多个端点。

这样的概念太抽象了,可以这样看:有一个设备,如支持视频和音频的一个播放器。那么,对于上面提到的4个描述符,对它们设置的时候,它们分别对于哪一个描述符呢?

从我现在的理解来看,这样一个设备对应一个设备描述符,支持视频的功能对应一个接口描述符,支持音频功能的对应一个接口描述符。为了支持视频,在下层有多个端口同时工作为提供视频数据传输的支持,所以有多个端点描述符

USB设备使用各种描述符来说明其设备架构,包括设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符,他们通常被保存在USB设备的固件程序中

1、设备描述符

设备代表一个USB设备,它由一个或多个配置组成。设备描述符用于说明设备的总体信息,并指明其所含的配置的个数。一个USB设备只能有一个设备描述符

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

2、配置描述符

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

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

3、接口描述符

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

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

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. {
  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. _ _u8 bRefresh;
  12. _ _u8 bSynchAddress;
  13. } _ _attribute_ _ ((packed));

5、字符串描述符

在USB设备中通常还含有字符串描述符,以说明一些专用信息,如制造商的名称、设备的序列号等。它的内容以UNICODE的形式给出,且可以被客户软件所读取。对USB设备来说,字符串描述符是可选的。

  1. struct usb_string_descriptor
  2. {
  3. _ _u8 bLength; //描述符长度
  4. _ _u8 bDescriptorType; //描述符类型
  5. _ _le16 wData[1];
  6. } _ _attribute_ _ ((packed));

6、管道

在USB系统结构中,可以认为数据传输时在USB主机软件与USB设备的各个端点之间直接进行的,它们之间的连接称为管道。管道是在USB设备的配置过程中建立的。管道是对USB主机与USB设备间通信流的抽象,表示USB主机的数据缓冲区与USB设备的端点之间存在着逻辑数据传输,而实际的数据传输是由USB总线接口层来完成的。

管道与USB设备中的端点一一对应。一个USB设备含有多少个端点,其与USB主机进行通信时就可以使用多少条管道,且端点的类型决定了管道中数据的传输类型,例如中断端点对应中断管道,且该管道只能进行中断传输。不论存在着多少条管道,在各个管道中进行的数据传输都是相互独立的。

7、USB端点分类

USB 通讯的最基本形式是通过端点。一个USB端点只能向一个方向传输数据(从主机到设备(称为输出端点)或者从设备到主机(称为输入端点))。端点可被看作一个单向的管道。

USB 端点有 4 种不同类型, 分别具有不同的数据传送方式:

1) 控制CONTROL 

控制端点被用来控制对USB设备的不同部分访问. 通常用作配置设备、获取设备信息、发送命令到设备或获取设备状态报告。这些端点通常较小。每个 USB 设备都有一个控制端点称为"端点 0", 被 USB 核心用来在插入时配置设备。USB协议保证总有足够的带宽留给控制端点传送数据到设备.

2) 中断INTERRUPT 

每当 USB 主机向设备请求数据时,中断端点以固定的速率传送小量的数据。此为USB 键盘和鼠标的主要的数据传送方法。它还用以传送数据到USB设备来控制设备。通常不用来传送大量数据。USB协议保证总有足够的带宽留给中断端点传送数据到设备.

3) 批量BULK

批量端点用以传送大量数据。这些端点通常比中断端点大得多. 它们普遍用于不能有任何数据丢失的情况。USB 协议不保证传输在特定时间范围内完成。如果总线上没有足够的空间来发送整个BULK包,它被分为多个包进行传输。这些端点普遍用于打印机、USB Mass Storage和USB网络设备上。

4) 等时ISOCHRONOUS 

等时端点也批量传送大量数据, 但是这个数据不被保证能送达。这些端点用在可以处理数据丢失的设备中,并且更多依赖于保持持续的数据流。如音频和视频设备等等。

控制和批量端点用于异步数据传送,而中断和等时端点是周期性的。这意味着这些端点被设置来在固定的时间连续传送数据,USB 核心为它们保留了相应的带宽。

  1. struct usb_host_endpoint{
  2. struct usb_endpoint_descriptor desc;//端点描述符
  3. struct list_head urb_list;//此端点的URB对列,由USB核心维护
  4. void *hcpriv;
  5. struct ep_device *ep_dev; /* For sysfs info */
  6. unsigned char*extra;/* Extra descriptors */
  7. int extralen;
  8. int enabled;
  9. };

当调用USB设备驱动调用usb_submit_urb提交urb请求时,将调用int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)把此urb增加到urb_list的尾巴上。(hcd: Host Controller Driver,对应数据结构struct usb_hcd )

Linux USB 驱动开发(一)—— USB设备基础概念【转】的更多相关文章

  1. 转: 嵌入式linux下usb驱动开发方法--看完少走弯路【转】

    转自:http://blog.csdn.net/jimmy_1986/article/details/5838297 嵌入式linux下的usb属于所有驱动中相当复杂的一个子系统,要想将她彻底征服,至 ...

  2. Linux驱动开发:USB驱动之usb_skel分析

    在学习了这么些天的驱动之后,个人觉得驱动就是个架构的问题,只要把架构弄清楚了 然后往里面添砖加瓦就可以了,所以似乎看起来不是太困难,但也许是是我经验不足吧,这只能算是个人浅见了 这两天在学习USB驱动 ...

  3. usb驱动开发5之总线设备与接口

    Linux设备模型中的总线落实在USB子系统里就是usb_bus_type,它在usb_init的函数bus_register(&usb_bus_type)里注册.usb_bus_type定义 ...

  4. HarmonyOS USB DDK助你轻松实现USB驱动开发

    HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...

  5. 《Linux设备驱动开发具体解释(第3版)》进展同步更新

    本博实时更新<Linux设备驱动开发具体解释(第3版)>的最新进展. 2015.2.26 差点儿完毕初稿. 本书已经rebase到开发中的Linux 4.0内核,案例多数基于多核CORTE ...

  6. Linux 设备驱动开发 —— platform设备驱动应用实例解析

    前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...

  7. Linux设备驱动开发环境的搭建(转)

    经过两周的摸索,终于对Linux设备驱动开发有了个初步的认识,下面对Linux设备驱动开发环境的搭建做个小结,以方便自己以后查询,同时也能给同道的初学者一点帮助. 刚接触Linux设备驱动时,初学者往 ...

  8. Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...

  9. Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...

  10. Linux设备驱动开发详解

    Linux设备驱动开发详解 http://download.csdn.net/detail/wuyouzi067/9581380

随机推荐

  1. sql学习--insert

    insert的四种插入方式 第一种最简单的 into 和目标列的列表是可选的 intsert [into] tableA [(col1,col2)] values(val1,val2) 第二种 ins ...

  2. matplotlib之pyplot 知识点滴

    以下是一些常用地址链接,请参考 matplotlib 官方网址 plt.plot()函数细节 Matplotlib 中文用户指南 4.6 编写数学表达式 Python seaborn matplotl ...

  3. android黑科技系列——Android中新型安全防护策略

    一.前言 最近有一个同学,发给我一个设备流量访问检测工具,但是奇怪的是,他从GP上下载下来之后安装就没有数据了,而在GP上直接安装就可以.二次打包也会有问题.所以这里就可以判断这个app应该是有签名校 ...

  4. 【PLSQL】游标

    Oracle中的SQL在执行时需要分配一块内存区域,这块内存区域叫做上下文区. 上下文区中记录了SQL语句的处理信息,这些信息包括:查询返回的数据行.查询所处理的数据的行号.指向共享池中的已分析的SQ ...

  5. 关于c# winform使用FidderCore.dll 遇到的一些问题,请求支援

    小弟最近再研究winform用fidder抓取包的过程.开始都很顺利,并且成功开启了代理网络.同时手机也设置代理,并且手机可以上网,而且电脑也能抓到手机的请求. 但是遇到两个问题. 1.,这里的关闭代 ...

  6. PHP stream_socket_server

    stream_socket_server - 创建一个Internet或Unix域服务器套接字 描述 资源stream_socket_server(字符串local_socket [摘要和错误号[,串 ...

  7. php多进程防止出现僵尸进程

    对于用PHP进行多进程并发编程,不可避免要遇到僵尸进程的问题. 僵尸进程是指的父进程已经退出,而该进程dead之后没有进程接受,就成为僵尸进程(zombie)进程.任何进程在退出前(使用exit退出) ...

  8. Selenium3+python 加载Firefox配置

    有小伙伴在用脚本启动浏览器时候发现原来下载的插件不见了,无法用firebug在打开的页面上继续定位页面元素,调试起来不方便 . 加载浏览器配置,需要用FirefoxProfile(profile_di ...

  9. 在 Linux 下判断系统当前是否开启了超线程

    转自: http://www.cnblogs.com/wjoyxt/p/4804293.html #lscpu Thread(s) per core: 2 Core(s) per socket: 6 ...

  10. SQL第二节课

    SQL练习题 一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的 ...