Linux USB 驱动开发(一)—— USB设备基础概念

在终端用户看来,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设备只能有一个设备描述符

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  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));  

2、配置描述符

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

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  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));  

3、接口描述符

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

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  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));  

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个。

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  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设备来说,字符串描述符是可选的。

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. struct usb_string_descriptor  
  2. {  
  3.     _ _u8 bLength; //描述符长度  
  4.     _ _u8 bDescriptorType; //描述符类型  
  5.       
  6.     _ _le16 wData[1];  
  7. } _ _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 核心为它们保留了相应的带宽。

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  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 )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401933.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux USB 驱动开发(四)—— 热插拔那点事

学习USB热插拔之前,先学习一些USB的硬件知识: 一、USB基础概念 1、硬件知识(USB插座和插头) 在最初的标准里,USB接头有4条线:电源,D-,D,地线。我们暂且把这样的叫做标准的USB接头吧。后来OTG出现…

Linux USB 驱动开发(五)—— USB驱动程序开发过程简单总结

设备驱动程序是操作系统内核和机器硬件之间的接口,由一组函数和一些私有数据组成,是应用程序和硬件设备之间的桥梁。在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。 设备驱动程序是…

android软键盘上推ui解决

为什么80%的码农都做不了架构师?>>> http://bbs.csdn.net/topics/340198955 android软键盘上推ui解决 good job 转载于:https://my.oschina.net/macleo/blog/204882

Linux USB 驱动开发实例(一) —— USB摄像头驱动实现源码分析

Spac5xx的实现是按照标准的USB VIDEO设备的驱动框架编写(其具体的驱动框架可参照/usr/src/linux/drivers/usb/usbvideo.c文件),整个源程序由四个主体部分组成: 设备模块的初始化模块和卸载模块,上层软件接口模块&#…

System Center 2012R2之SCVMM云部署SCOM(2-2)

SCVMM云部署SCOM安装过程1、在SCVMM中,使用WINDOWS SERVER 2012母盘创建云主机SCOM在SCVMM中先创建到一个私有云指定一个私有云名称选择资源主机指定逻辑网络默认选负载衡器跳过VIP模板跳过选择端口,下一步选择存储分类指定存储的VM路径各只读共享默认设…

Linux USB 驱动开发实例(二)—— USB 鼠标驱动注解及测试

参考2.6.14版本中的driver/usb/input/usbmouse.c。鼠标驱动可分为几个部分:驱动加载部分、probe部分、open部分、urb回调函数处理部分。 一、驱动加载部分 [cpp] view plaincopy static int __init usb_mouse_init(void) { int retval usb_register(&a…

MySQL5.6 更改字段属性仍旧会锁全表,注意这个坑!

如图:如果开发让修改表字段属性,建议用pt-online-schema-change。MySQL5.6的在线DDL会锁全表。注意这个坑。另外,增加、删除字段或索引不会锁全表,删除主键会锁全表。

Linux USB 驱动开发实例 (三)—— 基于USB总线的无线网卡浅析

回顾一下USB的相关知识 USB(Universal Serial Bus)总线又叫通用串行外部总线,它是20世纪90年代发展起来的。USB接口现在得到了广泛的应用和普及,现在的PC机中都带有大量的USB接口。它最大的特点就是方便通用、支持热插拔并且可以在一个接口上插上多个设备…

Linux 设备驱动开发思想 —— 驱动分层与驱动分离

前面我们学习I2C、USB、SD驱动时,有没有发现一个共性,就是在驱动开发时,每个驱动都分层三部分,由上到下分别是: 1、XXX 设备驱动 2、XXX 核心层 3、XXX 主机控制器驱动 而需要我们编写的主要是设备驱动部分&#xff0c…

CortexM0开发 —— UART时序分析

通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是一种异步收发传输器。将数据由串行通信与并行通信间作传输转换,作为并行输入成为串行输出的芯片UART是一种通用串行数据总线,用于异步通信。该总线…

CortexM0开发 —— LPC11C14的UART使用方法

LPC1100系列微控制器UART LPC1100系列Cortex-M0微控制器具有一个符合16C550工业标准的异步串行口(UART)。此口同时增加了调制解调器(Modem)接口,DSR、DCD和RI Modem信号是只用于LQFP48和PLCC44封装的管脚配置。 特性…

Linux SD卡驱动开发(一) —— SD 相关基础概念

一.SD/MMC卡基础概念 1.1.什么是MMC卡 MMC:MMC就是MultiMediaCard的缩写,即多媒体卡。它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低,传输速度快,广泛应用于消费类电子产品中。 1.2.什么是SD卡…

Linux SD卡驱动开发(二) —— SD 卡驱动分析HOST篇

回顾一下前面的知识,MMC 子系统范围三个部分: HOST 部分是针对不同主机的驱动程序,这一部是驱动程序工程师需要根据自己的特点平台来完成的。 CORE 部分: 这是整个MMC 的核心存,这部分完成了不同协议和规范的实现,并为…

MVC应用程序显示RealPlayer(rm)视频

本篇博文是演示MVC应用程序显示RealPlayer视频。 客户端能观看到RealPlayer视频,前提条件是需要安装RealPlayer客户端,就是想看Falsh或理WMV视频一样,均要安装客户端或相关插件等。 Insus.NET实现方法,还是在控制器中Render RealP…

Linux从入门到精通系列之PPTP

Linux从入门到精通系列之PPTP今天我们来说下怎么在linux环境下如何搭建PPTP-,PPTP(Point to Point Tunneling Protocol),即点对点隧道协议。该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用…

Linux SD卡驱动开发(三) —— SD 卡驱动分析CORE篇

废话不多说,直接切进主题: Linux在内核源码的drivers/mmc/core文件夹下为我们的提供了一系列SD卡的接口服务函数。可以查看Makefile如下 可见,core文件夹下有针对总线的服务bus.c,针对主控制器的服务host.c,针对SD卡的…

Python数值计算:一 使用Pylab绘图(1)

Pylab的使用 学习使用Python进行科学计算,然而很难找到简单实用,又循序渐进的例子。正好手边有一本《Matlab可视化大学物理学》,里面的例子非常清晰地解释了Matlab在物理学中的应用。重新使用Python实现这些例子,学习了Python&…

Linux SD卡驱动开发(四) —— SD 控制器之真正的硬件操作

前面对SD卡控制器有了一个基本的介绍。其实SD控制器层更过的意义是为core层提供一种操作SD卡硬件的一种方法,当然不同的控制器对硬件控制的方法不尽相同,但是他们最终都能像core层提交一个统一的封装有操作方法的数据结构,那便是即将闪亮登场…

Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇

Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述;另一个就是 mmc_add_host,用于注册host 前面探测函数s3cmci_probe,现在就来回顾一下这个函数的作用。先简要的概括一下这个函数的功能&#xff…

navicat连接oracle 报 ORA-12737 set CHS16GBK

2019独角兽企业重金招聘Python工程师标准>>> 1首 先,我们打开“工具”-->"选项"菜单,见到如下界面,依据OCI library(oci.dll) 路径,导航到 navicat oci 目录下,备份里面的文件(通过…