USB协议架构及驱动架构.docx

上传人:b****8 文档编号:8954220 上传时间:2023-05-16 格式:DOCX 页数:24 大小:651.75KB
下载 相关 举报
USB协议架构及驱动架构.docx_第1页
第1页 / 共24页
USB协议架构及驱动架构.docx_第2页
第2页 / 共24页
USB协议架构及驱动架构.docx_第3页
第3页 / 共24页
USB协议架构及驱动架构.docx_第4页
第4页 / 共24页
USB协议架构及驱动架构.docx_第5页
第5页 / 共24页
USB协议架构及驱动架构.docx_第6页
第6页 / 共24页
USB协议架构及驱动架构.docx_第7页
第7页 / 共24页
USB协议架构及驱动架构.docx_第8页
第8页 / 共24页
USB协议架构及驱动架构.docx_第9页
第9页 / 共24页
USB协议架构及驱动架构.docx_第10页
第10页 / 共24页
USB协议架构及驱动架构.docx_第11页
第11页 / 共24页
USB协议架构及驱动架构.docx_第12页
第12页 / 共24页
USB协议架构及驱动架构.docx_第13页
第13页 / 共24页
USB协议架构及驱动架构.docx_第14页
第14页 / 共24页
USB协议架构及驱动架构.docx_第15页
第15页 / 共24页
USB协议架构及驱动架构.docx_第16页
第16页 / 共24页
USB协议架构及驱动架构.docx_第17页
第17页 / 共24页
USB协议架构及驱动架构.docx_第18页
第18页 / 共24页
USB协议架构及驱动架构.docx_第19页
第19页 / 共24页
USB协议架构及驱动架构.docx_第20页
第20页 / 共24页
亲,该文档总共24页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

USB协议架构及驱动架构.docx

《USB协议架构及驱动架构.docx》由会员分享,可在线阅读,更多相关《USB协议架构及驱动架构.docx(24页珍藏版)》请在冰点文库上搜索。

USB协议架构及驱动架构.docx

USB协议架构及驱动架构

1.USB协议

1.1USB主机系统

      在USB主机系统中,通过根集线器与外部USB从机设备相连的处理芯片,称为USB主机控制器。

USB主机控制器包含硬件、软件和固件一部分。

1.2USB设备系统

       USB设备按功能分为两部分:

集线器(Hub)和功能部件。

从下图可知,主机通过根集线器连接到各种外围设备(集线器和功能部件)。

1.3主机和设备之间通信模型

    

                                           主机与设备之间的通信模型

       上图展示了USB主机和USB设备之间的数据传输过程。

在设备端,USB设备将非USB格式的数据进行打包处理,转换成USB格式的数据包,然后传递到链路层,经过硬件处理、传递到物理层,由物理层通过PHY以数据流的形式传输到主机。

 

      USB主机在USB设备和USB主机之间发起的传输过程,稳为事务。

每次事务以2到3个数据包的形式进行USB总线传输。

每个数据包包含2到3个步骤:

      1)USB主机控制器向USB设备发出命令

      2)USB控制器和USB设备之间传递读写请求,其方向取决于第一部分的命令是读还是写

      3)握手信号。

           USB主机控制器向USB设备发送事务类型请求,通过分组标识符来进行识别。

 1.4USB分组标识

       主机和设备之间进行操作,通过分组标识(PID)来进行传输。

数据包传输格式一般由:

PID、数据/控制信息、CRC校验码组成。

       常见的PID主要包括令牌、数据、握手等类型组成。

PID码以特定的方式组成,如下表所示:

     PID分组码是数据传输流程中的重要元素。

无论硬件还是软件,都要对PID分组码进行分析,从而做出正确响应。

USB主机和设备严格按照PID分组码信息进行信息交互。

1.5数据包传输模式

     当USB设备连接到集线器,集线器状态将发生相应的变化,并将状态变化信息传递给USB主机。

USB主机通过根集线器向USB设备发送命令,获取USB设备的各种信息,包含USB设备传输类型、ID号、Product、USB速度等信息。

     USB主机和USB设备之间的数据传输共有四种类型:

控制传输、批量传输、中断传输和同频传输。

与之对应,USB主机和USB设备之间有四种事务:

控制事务、批量事务、中断事务和同步事务。

1.5.1批量(Bulk)传输

   作用:

主要用于非实时性传输,数据包较大而延时要求较低。

   特点:

数据传输准备即可,采用批量传输模式的USB从机设备,如U盘

   数据传输分三个阶段:

   a) 令牌阶段:

主机发送请求,USB设备依据请求PID来判断IN或OUT传输

   b) 数据传输阶段:

依据令牌阶段的IN或OUT传输,来决定数据传输为DATA0或DATA1来进行数据传输

   c) 握手阶段:

接收信息的一方发送ACK信号以表示接收成功;若为NAK,表示发送失败;STALL表示不可预知的错误

 1.5.2控制(Control)传输

      作用:

USB传输过程必须支持的传输模式。

USB主机为了获取设备描述符、ID、Product等信息,向USB设备发送相应的PID命令。

      特点:

唯一可以进行IN/OUT传输的传输模式。

数据宽度:

控制传输方式可以以8、16、32或64字节的数据进行传输,这取决于设备的传输速度。

      USB主机和设备之间必须支持控制传输,通过端点0进行数据传输。

控制传输分为令牌、数据传输和握手阶段。

 1.5.3中断传输事务

作用:

按照一定时刻轮询设备是否有中断传输请求

特点:

查询频率取决于端点的模式结构,从1到255ms不等

中断传输主要用于实时性要求非常高的从机设备,如键盘操纵杆和Mouse等

传输过程也分为令牌阶段、数据传输和握手阶段 

1.6USB描述符

  USB协议中共定义了以下四种描述符:

  1)设备描述符

  2)配置描述符

  3)接口描述符

  4)端点描述符

  其关系如下图所示:

1.6.1设备描述符

     每个USB设备都有一个唯一的设备描述符,如下表所示:

1.6.2配置描述符

  每个USB设备都有默认的配置描述符,支持至少一个接口,每个配置描述符如下表:

 

1.6.3接口描述符

  设备应至少支持一个接口,如:

块传输数据接口,部分设备可能支持其它的接口。

复合设备可以支持额外接口,以支持音频和视频功能。

标准中并没有定义此类接口。

接口可能有多个可选设置,主机将会检查每个可选的设置。

1.6.4端点描述符

  每个设备至少支持控制端点0。

USB设备应该支持三类端点:

控制端点、输入端点和输出端点。

 2.OTG协议

       OTG设备采用Mini-AB插座,相对于传统的USB数据线,Mini-AB接口多了一根数据线ID,ID线是否接入将Mini-AB接口分为Mini-A和Mini-B接口两种类型。

在OTG设备之间数据连接的过程中,通过OTG数据线Mini-A和Mini-B接口来确定OTG设备的主从:

接入Mini-A接口的设备默认为A设备(主机设备);接入Mini-B接口的设备,默认为B设备(从设备)。

       A设备和B设备无需交换电缆接口,即可通过主机交换协议(HNP)实现A、B设备之间的角色互换。

同时,为了节省电源,OTG允许总线空闲时A设备判断电源。

此时,若B设备希望使用总线,可以通过会话请求协议(SRP)请求A设备提供电源。

2.1HNP(主机交换)协议

   当Mini-A接口接入A设备并确定A设备为主机时;若B设备希望成为主机,则A设备向B设备发送SetFeature命令,允许B设备进行主机交换。

B设备检测到总线挂起5ms后,即挂起D+并启动HNP,使总线处于SE0状态。

此时A设备检测到总线处于SE0状态,即认为B设备发起主机交换,A设备进行响应。

待B设备发现D+线为高电平而D-线为低电平(J状态),表示A设备识别了B设备的HNP请求。

B设备开始总线复位并具有总线控制权,主机交换协议完成。

2.2SRP(会话请求)协议

   对于主机,要求能响应会话请求;对于设备,仅要求能够发起SRP协议。

OTG设备,不仅要求发起SRP,而且还能响应SRP请求。

   SRP分为数据线脉冲调制和电压脉冲调两种方式,B设备发起SRP必须满足以下两个条件:

   1)B设备检测到A设备低于其有效的电压阈值,同时B设备低于有效的电压阈值。

   2)B设备必须检测到D+和D-数据线至少在2ms的时间内低于有效阈值,即处于SE0状态。

   数据线脉冲调制会话请求:

B设备必须等到满足以上两个条件后,将数据线接入上拉电阻一定的时间,以备A设备过滤数据线上的瞬间电压。

与此同时,B设备上拉D+以便于在全速模式下进行初始化操作。

A设备在检测到D+变为高电平或D-变为低电平时产生SRP指示信号。

    

   Vbus脉冲调制会话请求:

B设备同样需等待满足上述两个初始化条件,然后B设备通过对电容充电以提高总线电压,待达到总线上的电压阈值,唤醒A设备。

在充电过程中,一定要保证充电的电压峰值在一定的范围以避免烧坏A设备。

3.USB驱动架构

 

     USB驱动架构如下图所示:

 3.1USB主机端驱动

 

   USB核心(USBD)是整个USB驱动的核心部分,从上图可知,一方面USBD对接收到USB主机控制器的数据进行处理,并传递给上层的设备端驱动软件;同时也接收来自上层的非USB格式数据流,进行相应的数据处理后传递给USB主机控制器驱动。

   USB数据传输都以URB(USBRequestBlock)请求、URB生成、URB递交、URB释放为主线。

从上图可知,当加载控制器驱动之后,注册根据集线器,hub和hcd驱动成为一个整体。

接着,主机通过控制传输获取设备的控制描述符等信息,接着详述整个控制传输的流程。

usb_submit_urb依据是否连接到根集线器来决定调用urb_enqueue或rh_urb_enqueue函数。

   USB从设备通过集线器或根集线器连接到USB主机上。

比如:

主机通过根集线器与外界进行数据交互,根集线器通过探测数据线状态的变化来通知USB主机是否有USB外围设备接入。

   在主机端控制器驱动加载的过程中,注册了根集线器,然后匹配了相应的hub驱动程序,同时完成了对Hub的轮询函数和状态处理函数的设置。

这样,一旦hub集线器的状态发生变化,就会产生相应的中断,主机端控制器就会执行相应的中断处理函数,下图为hub驱动程序的流程图。

      USBCore中的usb_init()函数中完成了对hub线程(khubd,在usb_hub_init函数中真正地创建)的创建,然后完成相应设备的探测。

主机端控制器驱动进行探测时,将hub驱动和主机端控制器驱动结合在一起,相互之间完成调用。

相对于大容量存储设备与主机之间通过控制/批量传输,集线器与主机之间通过中断/控制方式完成数据交互。

3.2USB设备端驱动

 

   从上图可知,设备端驱动包含两部分:

   1)底层设备控制器驱动

   2)上层大容量存储类驱动

3.2.1设备控制器驱动

      USB设备控制器驱动主要实现GadgetAPI定义的函数和中断服务函数,可按功能划分为:

API函数实现模块和中断处理模块。

      API函数主要实现GadgetAPI定义的函数功能,如结构体usb_ep_ops和usb_gadget_ops中的函数、usb_gadget_register_driver函数。

这些函数是供GadgetDriver调用。

      中断处理模块主要处理设备控制器产生的各种中断,包括端点中断、复位、挂起等中断。

上图为设备端控制器基本架构,主要完成了Gadget驱动和控制器驱动绑定、usb_gadget_register_driver注册。

3.3OTG驱动

OS_FS:

文件系统

USBD:

USB核心

HCD:

主机控制器驱动

UDC:

设备端控制器驱动

      OTG设备支持HNP和SRP协议。

OTG设备通过USBOTG电缆连接到一起,其中接Mini-A接口的设备为A设备,默认为主机端,Mini-B接口的设备默认为B设备。

当A、B设备完成数据交互之后,A、B设备之间的USBOTG电缆进入挂起状态,如下图所示:

       当B设备写入b_bus_req,向A设备发起HNP请求。

待A设备响应之后,A设备发送a_set_b_hnp_en,B设备响应之后即进入主机状态,同时发送请求使用A设备set_device,这样A、B设备完成主从交换。

4.USB传输流程

 4.1USB初始化过程

      USB驱动作为一个系统,集成了众多的驱动模块,注册过程非常复杂。

从USB系统的角度来说,USB主机驱动主要包含:

      1)USB核驱动

       2)主机控制器驱动

      3)集线器驱动

      驱动的加载执行流程如下图所示:

                              USB初始化过程

4.1.1USBCore的初始化

  USB驱动从USB子系统的初始化开始,USB子系统的初始化在文件driver/usb/core/usb.c

[cpp] viewplaincopy

1.subsys_initcall(usb_init);  

2.module_exit(usb_exit);  

       subsys_initcall()是一个宏,可以理解为module_init()。

由于此部分代码非常重要,开发者把它看作一个子系统,而不仅仅是一个模块。

USBCore这个模块代表的不是某一个设备,而是所有USB设备赖以生存的模块。

在Linux中,像这样一个类别的设备驱动被归结为一个子系统。

subsys_initcall(usb_init)告诉我们,usb_init才是真正的初始化函数,而usb_exit将是整个USB子系统结束时的清理函数。

 

4.1.2主机控制器的初始化及驱动执行(以EHCI为例)

  module_init(otg_init);模块注册

  staticinit__initotg_init(void);

  platform_driver_register();平台注册

  staticint__initotg_probe(structplatform_device*pdev);探测处理函数

  reg=platform_get_resource(pdev,IORESOURCE_MEM,0);获取寄存器信息

  data=platform_get_resource(pdev,IORESOURCE_MEM,1);获取内存信息

  irq=platform_get_irq(pdev,0);获取中断号

  usb_create_hcd(&otg_hc_driver,&pdev->dev,pdev->dev.bus_id);

  分配和初始化HCD结构体。

对设备数据空间进行分配,初始化计数器、总线、定时器、hcd结构体各成员值。

  ret=usb_add_hcd(hcd,irq,SA_INTERRUPT);

  完成HCD结构体的初始化和注册。

申请buffer,注册总线、分配设备端内存空间,向中断向量表中申请中断,注册根集线器,对根集线器状态进行轮询。

4.1.3注册集线器

     register_root_hub(hcd);

    在USB系统驱动加载的过程中,创建了集线器的线程(khubd),并且一直查询相应的线程事务。

HCD驱动中,将集线器作为一个设备添加到主机控制器驱动中,然后进行集线器端口的初始化。

在USB主机看来,根集线器本身也是USB主机的设备。

USB主机驱动加载完成之后,即开始注册根集线器,并且作为一个设备加载到主机驱动之中。

      USB主机和USB设备之间进行数据交互,USB设备本身并没有总线控制权,U盘被动地接收USB主机发送过来的信息并做出响应。

USB主机控制器与根集线器构成了主机系统,然后外接其它的USB设备。

      为了更好地探测到根集线器的状态变化,USB主机控制器驱动增加了状态轮询函数,以一定的时间间隔轮询根集线器状态是否发生变化。

一旦根集线器状态发生变化,主机控制器就会产生相应的响应。

     USB主机和USB设备之间的数据传输以URB(USBRequestBlock)的形式进行。

 4.2URB传输过程

   USB初始化过程中,无论是主机控制器驱动还是根集线器驱动,都是通过URB传输获取设备信息。

4.2.1 申请URB

    structurb*usb_alloc_urb(intiso_packets,gfp_tmem_flags)

   为urb分配内存并执行初始化。

4.2.2初始化URB

    初始化具体的urb包 

[cpp] viewplaincopy

1.static inline void usb_fill_bulk_urb(struct urb *urb,  

2.     struct usb_device *dev,  

3.     unsigned int pipe,  

4.     void *transfer_buffer,  

5.     int buffer_length,  

6.     usb_complete_t complete_fn,  

7.     void *context)  

8.  

9.static inline void usb_fill_control_urb(struct urb *urb,  

10.    struct usb_device *dev,  

11.    unsigned int pipe,  

12.    unsigned char *setup_packet,  

13.    void *transfer_buffer,  

14.    int buffer_length,  

15.    usb_complete_t complete_fn,  

16.    void *context)  

17.static inline void usb_fill_int_urb(struct urb *urb,  

18.    struct usb_device *dev,  

19.    unsigned int pipe,  

20.    void *transfer_buffer,  

21.    int buffer_length,  

22.    usb_complete_t complete_fn,  

23.    void *context,  

24.    int interval)  

      不同的传输模式下,驱动为之申请不同的URB。

其中,Linux内核只支持同步传输外的三种传输事件,ISO事务需要手工进行初始化工作。

控制传输事务、批量传输事务、中断传输事务API如上所示。

     三种事务传输模式下的URB初始化函数有很多相似之处,主要参数含义如下:

     •urb:

事务传输中的urb

     •dev:

事务传输的目的设备

      •pipe:

USB主机与USB设备之间数据传输的通道

     •transfer_buffer:

发送数据所申请的内存缓冲区首地址

     •length:

发送数据缓冲区的长度

     •context:

complete函数的上下文

     •complete_fn:

调用完成函数

     •usb_fill_control_urb()的setup_packet:

即将被发送的设备数据包

     •usb_fill_int_urb()的interval:

中断传输中两个URB调度的时间间隔

4.2.3提交URB

      URB初始化完成之后,USBD开始通过usb_start_wait_urb()提交urb请求(它调用usb_submit_urb来真正的发送URB请求),添加completition函数。

     接下来,从message.c传到主机控制器(hcd.c),开始真正的usb_hcd_submit_urb()。

此时,根据是否为根集线器,进入不同的工作队列。

  usb_start_wait_urb->

  usb_submit_urb->

  usb_hcd_submit_urb

  a)root_hub传输

  若为roothub,将调用rh_urb_enqueue(),共有两种传输事务(控制传输和中断传输)

[cpp] viewplaincopy

1.static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)  

2.{  

3.    if (usb_endpoint_xfer_int(&urb->ep->desc)) // 中断传输  

4.        return rh_queue_status (hcd, urb);  

5.    if (usb_endpoint_xfer_control(&urb->ep->desc)) // 控制传输  

6.        return rh_call_control (hcd, urb);  

7.    return -EINVAL;  

8.}  

  b)非root_hub传输

  对于非常root_hub传输,它调用:

  status=hcd->driver->urb_enqueue(hcd,urb,mem_flags);

   c)批量传输

  root_hub本身没有批量传输流程,按照控制传输流程,控制传输最终要通过switch语句跳转到Bulk-Only传输流程中。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2