美文网首页USB
android usb2.0 协议基础

android usb2.0 协议基础

作者: xuefeng_apple | 来源:发表于2020-04-14 14:37 被阅读0次
    1-USB 基本知识
    2-USB 总线
    3-USB 设备
    4-USB 传输
    

    1-USB 基本知识

    USB的重要关键概念:
    1、 端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有惟一的确定地址,有不同的传输特性(如输入端点、输出端点、配置端点、批量传输端点)
    2、 帧:时间概念,在USB中,一帧就是1MS,它是一个独立的单元,包含了一系列总线动作,USB将1帧分为好几份,每一份中是一个USB的传输动作。
    3、upstream、downstream(上行、下行):设备到主机为上行,主机到设备为下行

    问题一:USB的传输线结构是如何的呢?
    一条USB的传输线分别由地线、电源线、D+、D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(注意哦,与CMOS的 5V电平不同),而电源线和地线可向设备提供5V电压,最大电流为500MA

    问题二:数据是如何在USB传输线里面传送的
    数据在USB线里传送是由低位到高位发送的。

    问题三:USB的编码方案?
    答案三:USB采用不归零取反来传输数据,当传输线上的差分数据输入0时就取反,输入1时就保持原值,为了确保信号发送的准确性,当在USB总线上发送一个包时,传输设备就要进行位插入***作(即在数据流中每连续6个1后就插入一个0),从而强迫NRZI码发生变化。这个了解就行了,这些是由专门硬件处理的。

    问题四:USB的数据格式是怎么样的呢?
    和其他的一样,USB数据是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)。下面简单介绍一下域、包、事务、传输,请注意他们之间的关系。

    2-USB 总线

    usb2.0 支持1.5Mb/s的低速(low-speed,鼠标..)模式和12Mb/s的全速(full-speed语音)模式,在USB2.0中,又加入了480Mb/s的高速模式(视频)。


    USB pin

    2.1 USB总线信号
    USB使用差分传输模式,两根数据线D+和D-
    差分信号1:D+>2.8V,D-<0.3V
    差分信号0:D->2.8V,D+<0.3V

    J状态和K状态
    低速下:D+为“0”,D-为“1”是为“J”状态,“K”状态相反;
    全速下:D+为“1”,D-为“0”是为“J”状态,“K”状态相反;
    高速同全速。

    SE0状态
    D+为“0”,D-为“0”

    IDLE状态
    低速下空闲状态为“K”状态;
    全速下空闲状态为“J”状态;
    高速下空闲状态为“SE0”状态.

    全速模式,有以下几个重要信号:
    Reset信号
    主机在要和设备通信之前会发送Reset信号来把设备配置到默认的未配置状态。即SE0状态保持10ms。

    Resume信号
    20ms的K状态+低速EOP

    Suspend信号
    3ms以上的J状态

    SOP信号
    从IDLE状态切换到K状态

    EOP信号
    持续2位时间的SE0信号,后跟随1位时间的J状态

    SYNC信号
    3个重复的K、J状态切换,后跟随2位时间的K状态

    2.2 USB信号数据编码
    USB采用NRZI(非归零编码)对发送的数据包进行编码。即:
    输入数据0,编码成“电平翻转”;输入数据1,编码成“电平不变”

    NRZI
    位填充是为了保证发送的数据序列中有足够多的电平变化。填充的对象时输入数据,即先填充后编码。数据流中每6个连续的“1”,就要插入1个“0”。
    接收方解码NRZI码流,然后识别出填充位,并丢弃它们。
    位填充
    位填充流程

    2.3 USB拓扑结构
    USB是一种主从结构的系统,主机叫做Host,从机叫做Device。Device包括USB function和USB HUB。
    USB总线基于分层的星状拓扑结构,以HUB为中心,连接周围设备。总线上最多可连接127个设备。Hub串联数量最多5个。

    bus 拓扑
    usb 实现区域
    usb 物理拓扑

    2.4 USB逻辑部件

    USB 逻辑部件
    设备
            ---》 接口 (一个或多个):用于描述特定功能,包含多个端点
                     ----》端点(一个或多个): 传输的最终对象
                              端点号,传输类型
                              传输方向,最大的数据长度....
    

    3-USB 设备

    3.1-USB 设备供电方式
    USB设备有两种供电方式:

    • 自供电设备:设备从外部电源获取工作电压
    • 总线供电设备: 设备从VBUS(5v)取点

    对总线供电设备,区分低功耗和高功耗USB设备。
    低功耗设备是最大功耗不超过100mA。
    高功耗设备是枚举时最大功耗不超过100mA,枚举完成配置结束后功耗不超过500mA。
    设备在枚举工程中,通过配置描述符来向主机报告它的供电方式和功耗要求的。


    USB full/high, low

    没有设备连上主机时,主机的D+和D-都在低电平(SE0状态),当SE0状态 持续一段时间了,就被主机认为是断开状态。
    当设备连上主机时,主机检测到某一数据线电平拉高并持续一段时间,就认为有设备连上来了。主机必须在复位设备前,立即采样总线状态来判断设备的速度。

    3.2-USB 设备状态
    USB设备有插入、供电、初始化、分配地址、配置和挂起六中状态,其状态转移图如下。

    设备状态

    3.3-USB 枚举过程


    USB 设备连接到主机或从主机上拔出时,主机通过枚举(Enumeration)过程来识别和管理设备。当一个设备连接到一个供电的端口时,将会有下列过程:

    1.------ 检测电压变化,报告主机:USB 设备上电后,HUB 检测到有电压变化,将利用自己的中断端点将信息反馈给主控制器有设备连接。

    主机了解连接设备:主机在知道有设备接入后会发送一个 Get_Port_Status 请求(request)给 hub 以了解此次状态改变的确切含义。

    Hub 检测所插入的设备是高速还是低速:hub 通过检测 USB 总线空闲(Idle)时差分线的高低电压来判断所连接设备的速度类型,当 host 发来 Get_Port_Status 请求时,hub 就可以将此设备的速度类型信息回复给 host。USB 2.0 规范要求速度检测要先于复位(Reset)操作。

    2.------hub 复位设备:主机一旦得知新设备已连上以后,它至少等待 100ms 以使得插入操作的完成以及设备电源稳定工作。然后主机控制器就向 hub 发出一个Set_Port_Feature 请求让hub 复位其管理的端口(刚才设备插上的端口)。hub 通过驱动数据线到复位状态(D+和 D-全为低电平),并持续至少 10ms。当然,hub 不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该 hub 上的设备自然看不到复位信号,不受影响。

    Host 检测所连接的全速设备是否是支持高速模式:根据 USB 2.0 协议,高速(High Speed)设备在初始时是默认全速(Full Speed )状态运行,所以对于一个支持 USB 2.0 的高速 hub,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。

    Hub 建立设备和主机之间的信息通道:主机不停地向 hub 发送 Get_Port_Status 请求,以查询设备是否复位成功。Hub 返回的报告信息中有专门的一位用来标志设备的复位状态。当 hub 撤销了复位信号,设备就处于默认/空闲状态(Default state),准备接收主机发来的请求。设备和主机之间的通信通过址 控制传输,默认地址 0 ,端点号 0 进行。此时,设备能从总线上得到的最大电流是 100mA。

    3&4.------ 主机发送 Get_Descriptor 请求 , 获取 设备描述符: :默认管道(Default Pipe)在设备一端来看就是端点 0。主机此时发送的请求是默认地址 0,端点 0。设备描述符的第 8 字节代表设备端点 0 的最大包大小。当完成第一次的控制传输后,系统会要求 hub 对设备进行再一次的复位操作。再次复位的目的是使设备进入一个确定的状态。

    **5.------ **主机给设备分配地址:主机控制器通过 Set_Address 请求向设备分配一个唯一的地址。此后,设备进入地址状态(Address state),之后就启用新地址继续与主机通信。
    6&7&8. 主机获取 设备的信息:主机再次发送 Get_Descriptor 请求到新地址读取设备描述符。设备描述符内信息包括端点 0 的最大包长度,设备所支持的配置(Configuration)个数,设备类型,VID、PID 等信息。之后主机发送Get_Descriptor 请求,读取配置描述符(Configuration Descriptor),字符串描述符等,逐一了解设备更详细的信息。配置描述符总共为 9 字节。主机在获取到配置描述符后,根据里面的配置集合总长度,再获取配置集合。配置集合包括配置描述符,接口描述符,端点描述符等。如果有字符串描述符,还要获取字符串描述符。另外 HID 设备还有HID 描述符等。

    主机给设备挂载驱动(复合设备除外):主机通过解析描述符后对设备有足够的了解,会选择一个最合适的驱动给设备。 然后调用设备模型提供的接口 device_add 将设备添加到usb 总线的设备列表里,然后 usb 总线会遍历驱动列表里的每个驱动,调用自己的match(usb_device_match)函数查询驱动和连入的设备或接口是否匹配,匹配的话调用device_bind_driver 函数,将控制权交到设备驱动。对于复合设备,通常应该是不同的接口(Interface)配置给不同的驱动,因此,需要等到当设备被配置并把接口使能后才可以把驱动挂载上去。

    9.------设备驱动选择一个配置:驱动根据前面设备回复的信息,发送 Set_Configuration 请求来正式确定选择设备的哪个配置(Configuration)作为工作配置。至此,设备处于配置状态(Configured),当然,设备也应该使能它的各个接口(Interface)

    上面的过程可以理解:(核心功能就是协商)

    Device:12 01 0100....Device Descriptor
    Host:你有几种功能?
    Device:09 02 09....Configuration Descriptor
    Host:每个功能有几个接口?
    Device:09 04 00....Interface Descriptor
    Host:每个接口使用哪几个端点?
    Device:06 05 82....Endpoint Descriptor
    Host:好了,我知道你是谁了,开始传输设备吧!
    Device:OK,Read Go!
    

    3.4-USB 描述符


    每种描述符的第一个字节描述该描述符包含的字节数目,第二个节描述该描述的类型。
    3.4.1 Device Descriptor

    3.4.2 Configuration Descriptor

    3.4.3 Interface Descriptor

    3.4.4 Endpoint Descriptor

    3.4.5 String Descriptor

    4-USB 传输

    USB总线上传输数据是以包(packet)为基本单位的,必须把不同的包组织成事务(transaction)才能传输数据。
    USB协议规定了四种传输(transfer)类型:批量传输、同步传输、中断传输和控制传输。其中,批量传输、同步传输和中断传输每传输一次数据都是一个事务,控制传输包括三个过程,建立过程和状态过程分别是一个事务,数据过程则可能包含多个事务。


    4.1 包packet
    一个包被分为不同域,根据不同类型的包,所包含的域是不一样的。但都要以同步域SYNC开始,紧跟一个包标识符PID,最终以包结束符EOP来结束这个包。

    packet
    • PID域
      PID是用来标识一个包的类型的。它共有8位,只使用4位(PID0PID3),另外4位是PID0PID3的取反,用来校验PID


      PID

      PID规定了四类包:令牌包、数据包、握手包和特殊包。同类的包又各分为具体的四种包



      仅在帧首传输一次SOF包。 (下面有介绍,令牌包)
    • 地址域
      地址共占11位,其中低7位是设备地址,高4位是端点地址。


      地址
    • 帧号域
      帧号占11位,主机每发出一个帧,帧号都会自加1,当帧号达到0x7FF时,将归零重新开始计数。

    • 数据域
      根据传输类型的不同,数据域的数据长度从0到1024字节不等。


    • CRC域
      校验和

    4.1.1 令牌包
    令牌包有四种:

    1-OUT: 通知设备将要输出一个数据包
    2-IN: 通知设备返回一个数据包
    3-SETUP: 只用在控制传输中,也是通知设备将要输出一个数据包,与OUT令牌的区别是:只使用DATA0数据包,且只能发到device的控制端点
    4-SOF: 在每帧开始时以广播的形式发送,针对USB全速设备,主机每1ms产生一个帧,USB主机会对当前帧号进行统计,每次帧开始时通过SOF包发送帧号。
    

    OUT/IN/SETUP令牌包没有帧号域和数据域。


    SOF令牌包没有地址域和数据域。


    4.1.2 数据包
    数据包没有地址域和帧号域。根据transfer的类型不同,数据包最大长度有所不同。

    4.1.3 握手包
    握手包有四种可选:

        ACK: 传输正确完成
        NAK: 设备暂时没有准备好接收数据,或没有准备好发送数据
        STALL: 设备不能用于传输
        NYET/ERR: 仅用于高速传输,设备没有准备好或出错
    

    握手包仅有PID域。


    4.2--事务:
    分别有IN、OUT和SETUP三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成,这里用阶段的意思是因为这些包的发送是有一定的时间先后顺序的,事务的三个阶段如下:
    1-令牌包阶段:启动一个输入、输出或设置的事务。
    2-数据包阶段:按输入、输出发送相应的数据。
    3-握手包阶段:返回数据接收情况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。

    事务的三种类型如下(以下按三个阶段来说明一个事务):

    4.2.1、 IN事务:
    令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;
    数据包阶段——设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)。

    1. 设备端点正常:设备往主机里面发出数据包(DATA0与DATA1交替);
    2. 设备正在忙:无法往主机发出数据包就发送NAK无效包,IN事务提前结束,到了下一个IN事务才继续;
    3. 相应设备端点被禁止:发送错误包STALL包,事务也就提前结束了,总线进入空闲状态。

    握手包阶段——主机正确接收到数据之后就会向设备发送ACK包。

    4.2.2、 OUT事务:
    令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
    数据包阶段——比较简单,就是主机会往设备送数据,DATA0与DATA1交替
    握手包阶段——设备根据情况会作出三种反应

    1. 设备端点接收正确,设备给主机返回ACK,通知主机可以发送新的数据,如果数据包发生了CRC校验错误,将不返回任何握手信息;
    2. 设备正在忙,无法给主机返回ACK,就发送NAK无效包,通知主机再次发送数据;
    3. 相应设备端点被禁止,发送错误包STALL包,事务提前结束,总线直接进入空闲状态。

    4.2.3、SETUT事务:
    令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
    数据包阶段——比较简单,就是主机往设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令
    //下面字节中含有的bit 位不同,命令也不同
    {标准的USB设备请求命令是用在控制传输中的“初始设置步骤”里的数据包阶段(即DATA0,由八个字节构成)。命令共有11个,大小都是8个字节,具有相同的结构,由5个字段构成(字段是标准请求命令的数据部分),结构如下(括号中的数字表示字节数,首字母bm,b,w分别表示位图、字节,双字节):
    bmRequestType(1) + bRequest(1) + wvalue(2) + wIndex(2) + wLength(2)
    }
    握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)。

    4.3 USB的四种传输类型:
    4.3.1. 控制传输:
    控制传输是一种可靠的双向传输,一次控制传输可分为三个阶段。
    第一阶段为从HOST到Device的SETUP事务传输,这个阶段指定了此次控制传输的请求类型;

    控制传输

    第二阶段为数据阶段,数据过程是可选的。一个数据过程包含一笔或者多笔数据事务。数据过程的第一个数据包必须是DATA1包,然后每次正确传输一个数据包就在DATA0和DATA1之间交替。
    第三阶段为状态阶段,状态过程也是一笔批量事务。状态过程只使用DATA1包。
    设备枚举过程中各种描述符的获取以及设置地址和设置配置等,都是通过控制传输来实现的。

    控制传输通过控制管道在应用软件和 Device 的控制端点之间进行,控制传输过程中传输的数据是有格式定义的,USB 设备或主机可根据格式定义解析获得的数据含义。

    其他三种传输类型都没有格式定义。
    控制传输对于最大包长度有固定的要求。对于高速设备该值为 64Byte;对于低速设备该值为 8;全速设备可以是 8或 16或 32或 64。

    最大包长度 表征了一个端点单次接收/发送数据的能力,实际上反应的是该端点对应的Buffer 的大小。Buffer 越大,单次可接收/发送的数据包越大,反之亦反。

    当通过一个端点进行数据传输时, 若数据的大小超过该端点的最大包长度时,需要将数据分成若干个数据包传输,并且要求除最后一个包外,所有的包长度均等于该最大包长度。

    这也就是说如果一个端点收到/发送了一个长度小于最大包长度的包,即意味着数据传输结束。

    控制传输在访问总线时也受到一些限制
    如: a. 高速端点的控制传输不能占用超过 20%的微帧,全速和低速的则不能超过 10%。
    b. 在一帧内如果有多余的未用时间,并且没有同步和中断传输,可以用来进行控制传输。

    4.3.2. 中断传输:
    中断传输是一种轮询的传输方式,是一种单向的传输,HOST通过固定的间隔对中断端点进行查询,若有数据传输或可以接收数据则返回数据或发送数据,否则返回NAK,表示尚未准备好。

    中断传输的延迟有保证,但并非实时传输,它是一种延迟有限的可靠传输,支持错误重传
    对于高速/全速/低速端点,最大包长度分别可以达到1024/64/8 Bytes。

    高速中断传输不得占用超过 80%的微帧时间,全速和低速不得超过 90%。

    中断端点的轮询间隔由在端点描述符中定义,全速端点的轮询间隔可以是1255mS,低速端点为10255mS,高速端点为(2interval-1)*125uS,其中 interval取 1到 16之间的值。

    除高速高带宽中断端点外,一个微帧内仅允许一次中断事务传输,高速高带宽端点最多可以在一个微帧内进行三次中断事务传输,传输高达 3072 字节的数据。

    所谓单向传输,并不是说该传输只支持一个方向的传输,而是指在某个端点上该传输仅支持一个方向,或输出,或输入。如果需要在两个方向上进行某种单向传输,需要占用两个端点,

    分别配置成不同的方向,可以拥有相同的端点编号。

    4.3.3. 批量传输:
    批量传输是一种可靠的单向传输,但延迟没有保证,它尽量利用可以利用的带宽来完成传输,适合数据量比较大的传输。

    低速 USB 设备不支持批量传输,高速批量端点的最大包长度为 512,全速批量端点的最大包长度可以为 8、16、32、64。

    批量传输在访问 USB 总线时,相对其他传输类型具有最低的优先级,USB HOST 总是优先安排其他类型的传输,当总线带宽有富余时才安排批量传输。

    高速的批量端点必须支持PING 操作,向主机报告端点的状态,NYET 表示否定应答,没有准备好接收下一个数据包,ACK 表示肯定应答,已经准备好接收下一个数据包。


    4.3.4. 同步传输:
    同步传输是一种实时的、不可靠的传输,不支持错误重发机制。只有高速和全速端点支持同步传输,高速同步端点的最大包长度为 1024,低速的为 1023。

    除高速高带宽同步端点外,一个微帧内仅允许一次同步事务传输,高速高带宽端点最多可以在一个微帧内进行三次同步事务传输,传输高达 3072 字节的数据。

    全速同步传输不得占用超过 80%的帧时间,高速同步传输不得占用超过 90%的微帧时间。 同步端点的访问也和中断端点一样,有固定的时间间隔限制。



    4.3.5 分离传输:
    在主机控制器和 USB HUB 之间还有另外一种传输——分离传输(Split Transaction),它仅在主机控制器和 HUB之间执行,通过分离传输,可以允许全速/低速设备连接到高速主机。

    分离传输对于USB 设备来说是透明的、不可见的。顾名思义就是把一次完整的事务传输分成两个事务传输来完成。其出发点是高速传输和全速/低速传输的速度不相等,如果使用一次完整的事务来传输,势必会造成比较长的等待时间,

    从而降低了高速 USB 总线的利用率。通过将一次传输分成两此,将令牌(和数据)的传输与响应数据(和握手)的传输分开,这样就可以在中间插入其他高速传输,从而提高总线的利用率。

    总结:USB的最小单元是“域”,由“域”构成了“包”,在由“包”构成了“事务”,最后由“事务”构成了“传输”,在应用层面,我们看到的只是传输,所以USB协议栈就需要完成传输以下的所有事情。这对标准的USB协议栈提出了最基本的要求, 优先级:同步传输 > 中断传输>控制传输>批量传输

    开发必备:
    枚举的过程实际上用到而且只用到了总线的“控制传输(Control Transfer)”。这种传输方式通常用于配置/命令/状态等情形,其中的设置操作setup和状态操作status过程的数据包具有USB协议定义的数据结构,因此,控制传输只能通过消息管道进行。
    一个完整的控制传输包括三个过程:

    1、建立连接。
    2、数据过程(可选) 。
    3、状态过程。

    建立连接的过程都是由Host发起,它开始于一个Setup令牌包,后面紧跟一个DATA0包。如果是控制输入传输,数据过程则为输入数据,若是控制输出传输,则数据过程是输出数据。

    数据过程的可选型是指设置过程需要指定数据长度,如果指定为0,则没有数据过程。状态过程跟在数据过程之后,状态过程恰好和数据过程的数据传输方向相反,因为此阶段主要是用来确认之前两阶段的所有数据都已经正确传输了。

    使用USB View 采集到的数据:

    Device Descriptor:
    bcdUSB:             0x0100
    bDeviceClass:         0xDC
    bDeviceSubClass:      0x00
    bDeviceProtocol:      0x00
    bMaxPacketSize0:      0x10 (16)
    idVendor:           0x0471
    idProduct:          0x0666
    bcdDevice:          0x0100
    iManufacturer:        0x00
    iProduct:             0x00
    iSerialNumber:        0x00
    bNumConfigurations:   0x01
    
    ConnectionStatus: DeviceConnected
    Current Config Value: 0x01
    Device Bus Speed:     Full
    Device Address:       0x02
    Open Pipes:              4
    
    Endpoint Descriptor:
    bEndpointAddress:     0x81
    Transfer Type:   Interrupt
    wMaxPacketSize:     0x0010 (16)
    bInterval:            0x0A
    
    Endpoint Descriptor:
    bEndpointAddress:     0x01
    Transfer Type:   Interrupt
    wMaxPacketSize:     0x0010 (16)
    bInterval:            0x0A
    
    Endpoint Descriptor:
    bEndpointAddress:     0x82
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x0A
    
    Endpoint Descriptor:
    bEndpointAddress:     0x02
    Transfer Type:        Bulk
    wMaxPacketSize:     0x0040 (64)
    bInterval:            0x0A
    

    REF:
    https://blog.csdn.net/u010142953/article/details/82627591
    https://blog.csdn.net/songze_lee/article/details/77658094
    https://www.cnblogs.com/qiyuexin/p/9043987.html#_label2_1

    相关文章

      网友评论

        本文标题:android usb2.0 协议基础

        本文链接:https://www.haomeiwen.com/subject/cmgwmhtx.html