Android设备间USB传输(OTG)

时间:2024-05-31 08:17:28

1. USB概述

    为了统一电脑和外围设备的接口标准,方便用户使用以及端口扩展,Intel和USB-IF组织于1994年开始开发一个通用总线标准-- USB(Universal Serial Bus),并在1995年发布USB1.0标准、2000年发展到USB2.0标准、目前已经更新到了USB3.0标准;另外,USB组织也在2004年提出了Wireless USB (无线USB)标准,以适应无线数据传输的趋势。USB标准主要从机械、电气、传输协议、系统设备组成以及软件结构等方面做了规范和描述。

1.1 USB机械标准

    USB标准中对USB传输线的构成(PVC保护层、镀锡铜编织、抗扰线等);USB插头、插口的分类,以及各自的具体尺寸,还有工作环境温度等进行了详细规范。另外,为了满足数码、移动设备的工作场景,USB插口、插头还有USB-Mini和USB-Mirco规范(主要是对接口的尺寸进行了重新定义)。

Android设备间USB传输(OTG)

图1 USB机械规范概览图

1.2  USB电气标准

    在电气方面:USB在不同速度下(Low-speed、Full-speed、High-speed)输入、输出驱动电路的阻抗要求,线路的信号传输延迟,设备电压敏感度,信号衰减,信号编解码方式(NRZI),信号有效范围等电气参数,USB标准都做了规范。

    在电源分配方面,由于连接到USB系统中的器件,连接线都会造成一定的压降,USB标准要求给下行端口的最低电压供给要带到4.35V,对于外接电源的Hub、总线供电的Hub、外界电源的设备、总线供电的设备还有其他不同的的规范要求。另外,USB标准规定所有连接设备都必须能够进入休眠,默认状态下休眠电流为500µ A,如果是支持唤醒或是high power端口,休眠电流为2.5mA。

    另外,USB标准规定,对于不同速度的设备鉴别需要硬件上不同的连接(如图2):低速设备需要在D-接上拉电阻、全速设备需要在D+接上拉电阻、而USB对于高速设备规定需要有一个电流驱动器(通过电流驱动器灌到D+/D-上产生压降)。当不同速率的设备连接时,USB主设端正是通过D-/D+上的电压变化来识别区分的。

Android设备间USB传输(OTG)

图2  USB不同速度设备硬件连接

1.3  USB系统组成

    USB标准中将USB系统描述为三个部分:USB主设、USB从设、设备间联通。一个USB主设需要根据协议对数据的传输增加相应的协议信息以及协议的解析(Protocol Engine);需要对传输的数据进行串行化及解串行化(SIE-Serial Interface Engine);需要对数据传输的差错进行检测、处理(ErrorHandling)等:

Android设备间USB传输(OTG)

图3 USB Host Controler架构

而软件层上需要对USB主设进行控制,读取信息等工作(Host Controler Driver);同时需要有一部分软件对连接到USB主设上的从设备进行管理、控制(USB Device Driver);由于对特定从设备的管理、控制的数据最终还是需要经过USB主设实际发送,因此在HCD和UDD之间有一个中间层(Host Core Driver)。

    USB从设也需要一个协议引擎来按照USB协议标准发送、接收信号;另外USB从设有许多可寻址的FIFO缓冲区,USB主设具体上就是和这些FIFO进行数据交互。同样,在软件架构上,USB从设也有和USB从控制器交互的Device Controler Driver以及和从设上的具体设备进行交互的USBGadget Driver,中间层则是Device Core Driver。

Android设备间USB传输(OTG)

图4 USB Device Controler架构

    在USB系统中除了以上介绍的USB主设和USB从设外,还有一个设备可以对USB端口进行有效的扩展和管理—USBHub。USB Hub实际上在USB系统中是一个特殊的USB从设备,它有着特定的设备描述符以及相关组件来完成它在USB系统中的功能。

Android设备间USB传输(OTG)

图5 USB Hub框图

USB Hub一般会有多个端口用来和其他USB从设备进行连接(USBDownstream)以及一个和USB主设备连接的端口(USB Upstream);USB Hub作为一个从设备的身份也需要和USB主设备进行数据交互(Hub Controler);而USB Hub作为连接USB主设备和USB从设备的中间设备,需要对上行端口和下行端口的数据传输进行管理(Hub Repeater);另外,对于连接到Hub上的不同速度的设备,需要一个组件(Transaction Translator)把一个速度的数据转换到另一个速度进行传输。USBHub最重要的一个功能是将连接到Hub上的从设备上报给USB主设备,USB Hub中有一个特殊的Endpoint FIFO专门来保存Hub端口上的状态。

    USB系统就是由以上的设备和传输协议以及其他规范来组成USB系统。主设端有Host设备控制器,和Host设备控制器直接连接的根Hub,向下再连接其他从设备或其他Hub,组成一个级联的系统。

Android设备间USB传输(OTG)

图6 USB系统拓扑图

2  USB OTG

2.1  OTG概述

    USB OTG(On The Go)作为USB2.0的补充协议,于2001年由USB-IF提出。它提出的背景是移动消费类电子产品的迅猛增加,而之前USB协议的主从协议标准让这些电子产品在离开PC电脑时的数据传输变得艰难,OTG技术正是为了解决这一问题的标准。

Android设备间USB传输(OTG)

图7  通过OTG技术实现设备间端到端互联

    OTG协议规定连接时默认情况作为Host的设备为A设备,A设备负责为总线供电;默认作为Device的设备为B设备(USB OTG标准在完全兼容USB2.0标准的基础上,增加了一个ID pin;ID拉低为默认A设备);而有些设备由于集成了Host控制器和Device控制器,既可以作A设备又可以做B设备,称为dura-role device。

2.2  OTG 相关协议

AttachDetection Protocol (ADT)

    ADT协议用来检测设备的连接和断开(在没有总线供电的情况下),原理为设备连接或断开后线路的阻抗发生变化,发起ADT探测的设备用一电流源给Vbus升到一定电压的时间会不同。

SessionRequest Protocol (SRP)

    SRP用来请求A设备给Vbus进行供电。由于一般的移动电子设备对功耗要求比较高,因此OTG标准允许A设备平常关闭对总线的供电,而B设备就可以使用SRP 请求A设备打开Vbus,建立一个有效的连接。

Host Negotiation Protocol (HNP)

    对于之前提到过的dual-roledevice,即可以做A设备又可以做B设备。默认情况下是根据USB OTG线的连接情况确定A设备,而HNP可以让dual-role device互联时,在不调换USB OTG线的情况下,通过协商实现A设备、B设备的角色更换。

2.3  OTG软件架构

    根据USB OTG的电气和机械标准,USBOTG Controler需要支持一系列的OTG协议;而Controler Driver理所当然的就需要和这个Controler进行交互,读取状态、发起操作等;当完成了OTG的检测连接、建立连接的工作后,最终需要去让相应USB设备的Host Controler或者Device Controler去进行数据传输,OTG Driver Core则负责这个工作。


Android设备间USB传输(OTG)

图8 OTG软件架构

3  Android下USB驱动开发

    根据之前的介绍,进行USB传输的驱动开发在从设备端需要进行Gadget Driver的开发;在设备端需要进行Host Device Driver的开发。而之前介绍的相应Controler的驱动由于是直接和相关硬件控制器交互,一般由芯片厂商或者平台端完成。由于USB设备的普及应用,USB标准对一些通用的设备:键盘、鼠标、U盘等做了规范,即不同的设备类(USBClass)。对于这些通用设备,由于设备端按照标准进行设计、固件程序由厂商按照标准实现;主机端有对应的标准驱动程序,因此只要安装相应驱动即可。对于自定义的设备或是功能来说:

3.1  Host端驱动开发

    由于HostControler Driver做的工作以及Host Core Driver提供的完善接口,这里的Host端驱动开发相对来说已经是比较简单了。

    当设备的连接探测、设备信息获取等一系列操作完成后,会遍历注册到核心的Host Device Driver为连接到Host端的设备寻找一个控制驱动,因此在编写驱动时需要写好自己的匹配规则;当编写的驱动注册到后,核心会创建一个字符设备,用户空间一般就通过这个字符设备来读写USB设备,因此驱动中实现读写等其他设备操作接口是最重要的一部分内容。

Android设备间USB传输(OTG)

图9 Host端驱动开发步骤

对于USB设备的读写,之前有提到过在从设备端有多个EndPoint(可寻址的FIFO),所以读写接口的实现就是对这些EndPoint进行操作。USB设备中的端点除了0号端点是双向的(用来初始获取设备信息使用),其他端点都是单向的。读/写接口需要和IN/OUT端点交互,调用核心提供的接口从IN端点中读或者向OUT端点中写。

Android设备间USB传输(OTG)

图10 Host和端点进行数据传输

对于数据传输的方式,USB标准规范了四种传输方式:控制传输(Control Transfers)、中断传输(InterruptTransfers)、同步传输(Isochronous Transfers)、块传输(Bulk Transfers)。USB主机通过控制传输向USB设备读取信息、配置;中断传输具有固定速率、数据量少的数据传输;同步传输适合实时流传输,但是不保证数据正确性;块传输适合大量数据传输,提供错误检测和重传机制。在实际程序中,选定不同的传输方式,只需要使用不同的内核接口即可,而具体的协议过程会由硬件控制器及其驱动来完成。

    对应于具体函数,可以参考内核中的usb-skeleton.c对应进行了解。对于主要的接口和基本的编写过程下面提供一个简单的草图:

Android设备间USB传输(OTG)

图11 Host端驱动具体函数草图


3.2   Device端驱动开发

    对于Android设备来说,属于USB复合设备(设备上有多个通过USB管理控制的功能)。为了方便用户使用,android将每种功能对应的gadgetdriver做了重新组织并和应用层交互:

Android设备间USB传输(OTG)

图12 Android下USBdevice端驱动组织

在这样的架构下,USB gadget driver做的事情就是描述自己属于何种类型的设备,USB Host可以访问的端点有哪些、端点的性质,读取端点、填充端点的具体方式。

    USB从设备利用描述符(Descriptor)来表明设备的属性,USB标准规定了各种不同的描述符,以及描述符的具体内容,USB主设备通过获得这些描述符的信息来判断连接设备的类型、功能等一系列信息。一般来说,USB gadget driver中需要关心的描述符有:设备描述符、接口描述符、端点描述符、配置描述符,这里面端点描述符描述EndPoint的方向、大小、地址等信息;设备描述符描述设备的生产商信息、设备类、遵循协议等信息;其他描述符可以认为是逻辑上的(一个接口对应一个功能,它对应着一个驱动)。

Android设备间USB传输(OTG)

图13 USB从设备描述符及逻辑关系

    在Android对数据结构的组织和composite框架下,如果需要新加一个USBgadget driver只需要填充好Android提供的一个函数指针结构体,在一个bind_config接口中去把实现好的composite框架规定的接口加入composite框架中去,具体的端点操作可以在一些可选的接口中维护自己的读写接口(一般在init中注册设备)。详细可参见f_adb.c文件。

Android设备间USB传输(OTG)

图14 Android下新加功能需要关注