USB

USB学习笔记


未曾清贫难做人,不经打击永天真;成熟不过是善于隐藏,沧桑不过是无泪有伤;人生于世,委屈在所难免,消化了就是成长的动力,消化不了就会变成脾气。


  • 拓扑结构

    USB是一种主从结构的系统。主机叫Host, 从机叫做Device,也叫做设备。

    通常所说的主机具有一个或多个USB主控制器(host controller)和根集线器(root hub)。主控制器主要负责数据处理,根集线器则提供一个连接主控制器与设备之间的接口和通路。

    另外,有一类特殊的USB设备,USB集线器(USB hub),它可以对原有的USB口在数量上进行扩展,可以获得更多的USB口。

    USB的数据交换只能发生在主机与设备之间,主机与主机、设备与设备之间不能直接互连和交换数据。所有的数据传输都由主机主动发起,而设备知识被动的负责应答。

    一个完整的USB数据传输过程如下:首先有USB主控制器发出命令和数据,通过根集线器,再通过下面的集线器(如果有)发给USB设备;设备对接收到的数据进行处理后,返回一些信息或数据,它首先到达其上一层的集线器,上层的集线器再交给更上层的集线器,一直到USB主控制器为止;最终,USB主控制器将数据交给计算机的CPU处理。

  • USB的电气特性

    标准的USB连接线使用4芯电缆:5V电源线(Vbus)、差分数据线负(D-)、差分数据线正(D+)及地(GND)。在USB OTG中,又增加了一种MINI USB接头,使用的是5条线,比标准的USB多了一条身份识别(ID)线。

    USB2.0支持3种传输速度:低速模式(1.5Mb/s)、全速模式(12Mb/s)以及高速模式(480Mb/s)。传输速度是指总线上每秒传输的位数,实际的数据速率要比这个速度低一些,因为有很多协议开销,例如同步、令牌、校验、位填充和包间隙等。

    在USB的低速和全速模式中,采用的是电压传输模式;而在高速模式下,采用的是电流传输模式。

    USB使用的是NRZI编码方式:当数据为0时,电平翻转;数据为1时,电平不翻转。为了防止出现长时间电平不变化(这样不利于时钟信号的提取),在发送数据前要经过位填充(bit stuffing)处理。处理过程是:当遇到连续6个数据1时,就强制插入一个数据0。经过位填充后的数据,由串行接口引擎(SIE)将数据串行化和NRZI编码后,发送到USB的差分数据线上。在接收端,刚好是一个相反的过程。接收端采样数据线,有SIE将数据并行化(反串行化),然后去掉位填充(反位填充),恢复出原来的数据。通常,我们使用线程的USB芯片,如位填充、串行化、反串行化、CRC校验等处理过程,芯片内部的硬件都会处理。如果是自己设计一个USB核,或使用软件来模拟USB口,那这些过程就需要自己来做了。

USB的NRZI示意图

USB的NRZI示意图

  • USB的插入检测机制

    在USB集线器的每个下游端口的D+和D-上,分别接了一个15kΩ的下拉电阻到地。这样,当集线器的端口悬空(没有设备插入)时,输入端口就被这两个下拉电阻拉倒了低电平。而在USB设备端,在D+或者D-上接了一个1.5kΩ的上拉电阻到3.3V电源。1.5kΩ的上拉电阻接在D+上还是D-上,有设备的速度来决定。对于全速设备和高速设备,上拉电阻接在D+上,而低速设备的上拉电阻则是接在D-上。速度快的接正,速度慢的接负。

    当设备插入到集线器时,接了上拉电阻的那条数据线的电压由1.5kΩ的上拉电阻和15kΩ的下拉电阻分压决定,结果大概在3V左右。这个对集线器的接收端来说,是一个高电平信号。集线器检测到这个状态后,就报告给USB主控制器(或者通过它的上一层集线器报告给USB主控制器),这样就检测到设备插入了。集线器根据检测到被拉高的数据线是D+还是D-来判断插入的是什么速度类型的设备。USB高速设备先是被识别为全速设备,然后通过集线器和设备两者的确认,再切换到高速模式下。在高速模式下,是电流传输模式,这时要将D+上的上拉电阻断开。

  • USB的描述符

    一个USB设备只有一个设备描述符。设备描述符里决定了该设备有多少种配置,每种配置有一个配置描述符;而在每个配置描述符中又定义了该配置里有多少个接口,每个接口都有一个接口描述符;在接口描述符里定义了该接口有多少个端点,每个端点都有一个端点描述符;端点描述符定义了端点的大小、类型等。如果有类特殊描述符,它跟在相应的接口描述符之后。由此可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,接下来是配置描述符,再接下来是接口描述符,最下面是端点描述符。主机获取描述符时,首先获取设备描述符,接着再获取配置描述符,然后根据配置描述符中的配置集合的总长度,一次将配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符一次读回。字符串描述符时单独获取的。主机通过发送获取字符串描述符的请求已经描述符的索引号、语言ID来获取对应的字符串描述符。

    设备描述符(Device Descriptor)

    主要记录的信息有:设备所使用的USB协议版本号、设备类型、端点0的最大包大小、厂商ID(VID)和产品ID(PID)、设备版本号、厂商字符串索引、产品字符串索引、设备序列号索引、可能的配置数等

    配置描述符(Configuration Descriptor)

    主要记录的信息有:配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等

    接口描述符(Interface Descriptor)

    主要记录的信息有:接口的编号、接口的端点数、接口所使用的类、子类、协议等

    端点描述符(Endpoint Descriptor)

    主要记录的信息有:端点号及方向、端点的传输类型、最大包长度、查寻时间间隔等

    字符串描述符(String Descriptor)

    主要提供一些方便人阅读的信息,不是必须的。


    Device Qualifier Descriptor

    Other Speed Configuration Descriptor

  • USB设备的枚举过程

    USB主机在检测到USB设备插入后,要对社保进行枚举。枚举就是从设备读取各种描述符信息,这样主机就可以根据这些信息来加载合适的驱动程序,从而知道设备是什么样的设备,如何进行通信等。

    控制传输

    控制传输在USB中是非常重要的,它保证数据的正确性。控制传输分为三个过程:建立过程、数据过程(可选)及状态过程

    建立(setup)过程都是由USB主机发起的。它开始于一个SETUP令牌包,后面紧跟一个DATA0数据包,接着就是数据过程。如果是控制读传输,那么数据过程就是输入数据;如果是控制写传输,那么数据过程是输出数据。如果在建立过程中,指定了数据长度为0, 则没有数据过程。数据过程之后是状态过程。状态过程刚好与数据过程的数据传输方向相反;如果是控制读传输,则状态过程是一个输出数据包;如果是一个控制写传输,则状态过程是一个输入数据包。状态过程用来确认所有的数据是否都已经正确传输完成。

    枚举的详细过程:

    ①USB主机见到到USB设备插入后,就会先对设备复位。USB设备在总线复位后其地址为0,这样主机就可以通过地址0和插入的设备通信。USB主机往地址为0的设备的端点0发送获取设备描述符的标准请求(控制传输的建立过程)。设备收到该请求后,会按照主机请求的参数,在数据过程将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符并且确认没有错误后,就会返回一个0长度的确认数据包(状态过程)给设备, 从而进入到接下来的设置地址阶段。

    需要注意的是,第一次主机只会读取一个数据包的设备描述符。标准的设备描述有18个字节,有些USB设备的端点0大小不足18个字节(但至少有8个字节),在这中情况下,USB主机也是只发送一次数据输入请求,多余的数据将不会再次请求。因此,如果设备端点0大小不足18字节时,就需要注意到这个问题。也就是说在第一次获取设备描述符时,只需要返回一次数据即可,不要再等到主机继续获取剩余数据(如果还有),因为主机不会这样操作。当主机成功获取到设备描述符的前8个字节后(USB协议规定端点0最大包长至少要有8个字节),它就知道端点0的最大包长度了,因为端点0最大包长度在设备描述符的第8个字节。

    ②主机对设备又一次复位。这时就进入到了设置地址阶段。USB主机往地址为0的设备端点0发出一个设置地址的请求(控制传输的建立过程), 新的设备地址包含在建立过程的数据包中。具体的地址由USB主机负责管理,主机会分配一个唯一的地址给刚接入的设备。USB设备在收到这个建立过程之后,就直接进入到状态过程,因为这个控制传输没有数据过程。设备等待主机请求状态返回(一个输入令牌包),收到输入令牌包后,设备就返回0长度的状态数据包。如果主机确认该状态包已经正确接收,就会发送应答ACK给设备,设备在收到这个ACK后,就要启动新的设备地址了。这样设备就分配到了一个唯一的设备地址,以后主机就通过它来访问该设备。

    ③主机再次获取设备描述符。这次和第一次有点不一样,首先是主机不在使用地址0来访问设备,而是心的设备地址;另外,这次需要获取全部的18字节的设备描述符。如果你的端点0最大包长度小于18,那就会多次请求数据输入(即发送多个IN令牌包)。

    ④主机获取配置描述符。配置描述符总共为9个字节。主机在获取到配置描述符后,根据配置描述符中所描述的配置集合总长度获取配置集合。获取配置描述符和获取配置描述符集合的请求是差不多的,只是指定的长度不一样。有些主机干脆不单独获取配置描述符,而是直接使用最大长度来获取配置描述符集合,因为设备实际返回的数据可以少于指定的字节数。配置集合包括配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符等。接口描述符、类特殊描述符、端点描述符时不能单独获取的,必须跟随配置描述符以一个集合的方式一并返回。

    ⑤如果有字符串描述符,还有获取字符串描述符。另外想HID设备还有报告描述符,他们是单独获取的。

  • USB的包结构及传输过程

    1. USB的包结构及包的分类

      USB总线上传输数据是以包为基本单位的。一个包被分成不同的域。根据不同类型的包,所包含的域是不一样的。但是不同的包有个共同的特点,就是都要以同步域开始,紧接着一个包标识符PID(Packet Identifier),最终以包结束符EOP(End Of Packet)来结束这个包。

      同步域是用来告诉USB的串行接口引擎数据要开始传输了,请做好准备。除此之外,同步域还可以用来同步主机端和设备端的数据时钟,因为同步域是以一串0开始的,而0在USB总线上就被编码为电平翻转,结果就是每个数据位都发生电平变化,这让串行接口引擎很容易就能恢复出采样时钟信号;对于全速设备和低速设备,同步域使用的是00000001(二进制数,总线上的发送顺序);对于高速设备,同步域使用的是31个0,后面跟1个1(需要注意的是,这是对发送端的要求,接收端解码时,0的个数可以少于这个熟)。

      包标识符PID是用来标识一个包的类型的。总共有8位,其中USB协议使用的只有4位(PID0-PID3),另外4位(PID4-PID7)是PID0-PID3的取反,用来校验PID。USB协议规定了4类包,分别是:

      令牌包(token packet, PID1-PID0为01)

      数据包(data packet, PID1-PID0为11)

      握手包(handshake packet, PID1-PID0为10)

      特殊包(special packet, PID1-PID0为00)

      不同类的包有分成几种具体的包。

      包结束符EOP,对于高速设备和全速设备/低速设备也是不一样的。全速/低速设备的EOP是一个大约为2个数据位宽度的单端0(SE0)信号。SE0的意思就是,D+和D-都保持低电平。由于USB使用的是差分数据线,通常都是一高一低的,而SE0不同,是一种都是低特殊状态。SE0用来表示一些特殊的意义,例如包结束、复位信号等。USB集线器对USB设备进行复位的操作,就是通过将总线设置为SE0状态大约10ms来实现的。对于高速设备的EOP,使用故意的位填充错误来表示。那么如何判断一个位填充错误是真的位填充错误还是包结束呢?这个有CRC校验来判断。如果CRC校验正确,则说明这个位填充错误是EOP;否则说明传输错误。

    2. USB的包结构及包的分类

      令牌宝用来启动一次USB传输,有4种:

      分别为输出(OUT)

      输出令牌包用来通知设备将要输出的一个数据包

      输入(IN)

      输入令牌包用来通知设备返回一个数据包

      建立(SETUP)

      建立令牌包只用在控制传输中,它和输出令牌包作用一样,也是通知设备将要输出一个数据包, 两者的区别:SETUP令牌包值使用DATA0数据包, 且只能发到设备的控制端点,并且设备必须要接收, 而OUT令牌包没有这些限制。

      OUT、IN、SETUP令牌包具有相同的结构:同步域、包标识域、地址域、端点域、CRC5校验域和包结束。

      OUT IN SETUP令牌包结构

      帧起始(SOF Start Of Frame)。

      帧起始包在每帧(或微帧)开始时发送,它以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。USB全速设备每1ms产生一个帧,而高速设备每125us产生一个微帧。USB主机会对当前帧号进行计算,在每次帧开始时(或微帧开始时,每1ms有8个微帧, 这8个微帧的帧号是一样的,即相同的SOF)通过SOF包发送帧号。SOF的帧号是11位的。在4个令牌包中,只有SOF令牌包之后不跟随数据传输,其他的都有数据传输。

      SOF令牌包结构

    3. 数据包

      在USB1.1协议中有两种数据包DATA0包和DATA1包。在USB2.0中增加了DATA2和MDTA包,主要用的高速分裂事务和高速高带宽同步传输中。

    数据包结构

    数据包都具有同样的结构:一个同步域,后面跟整数字节的数据,然后是CRC16校验,最后是包结束符EOP。

    主机和设备都会维护自己的一个数据包类型切换机制:当数据包成功发送或接收,数据包类型切换。当检测到对方所使用的数据包类型不对时,USB系统认为发生了一个错误,并试图从错误中恢复。数据包类型不匹配主要发生在握手包被损坏的情形。当一段已经正确接收到数据并返回确认信号时,确认信号却在传输过程中被损坏。这时另一段就无法知道刚刚发送的数据是否已经成功,这时它只好保持自己的数据包的类型不变。如果对方下一次使用的数据包类型和自己的不一致,则说明它刚刚已经成功接收到数据包了(因为它已经做了数据包切换,只有正确接收才会如此);如果对方下一次使用的数据包类型和自己的一致,则说明对方没有切换数据包类型,也就是说,刚刚的数据包没有发送成功,这是上一次的重试操作。

    1. 握手包

      握手包只有同步域、PID和EOP

      握手包结构

      握手包有:

      ACK

      ACK表示正确接收数据,并且有足够的空间来容纳数据。主机和设备都可以用ACK来确认,而NAK、STALL、NYET只有设备能够返回,主机不能使用这些握手包。

      NAK

      NAK表示没有数据需要返回,或者数据正确接收但是没有足够的空间来容纳。当主机收到NAK时,知道设备还未准备好,主机会在以后合适的时机进行重试传输。

      STALL

      STALL表示设备无法执行这个请求,或者端点已经被挂起了,它表示一种错误的状态。设备返回STALL后,需要主机进行干预才能解除这中STALL状态。

      NYET

      NYET只在USB2.0的高速设备输出事务中使用,它表示设备本次数据接收成功,但是没有足够的空间来接收下一次数据。主机在下一次输出数据时,将先使用PING令牌包来试探设备是否有空间接收数据,以免不必要的带宽浪费。

      注意:返回NYET并不表示数据出错,只是说明设备暂时没有数据传输或者暂时没有能力接收数据。当USB主机或设备检测到数据错误时(如CRC校验错误、PID校验错误、位填充错误等),将什么都不返回。这时等待接收握手包的一方就会收不到握手包从而等待超时。

    2. 特殊包

      特殊包是一些特殊场合使用的包。总共有4种:PRE、ERR、SPLIT、PING。其中PRE、SPLIT、PING是令牌包,ERR是握手包。ERR、SPLIT、PING三个是在USB2.0协议中新增的。

      PRE是通知集线器打开低速端口的一种前导包。PRE只使用在全速模式中。平时,为了防止全速信号使低速设备误操作,集线器时没有将全速信号传递给低速设备的。只有当收到PRE令牌包时,才打开低速端口。PRE令牌包与握手包的结构一样,只有同步域、PID和EOP。当需要传送低速事务时,主机首先发送一个PRE令牌包(以全速模式发送)。对于全速设备,将会忽略这个令牌包。集线器再收到这个令牌包后,打开其连接了低速设备的端口。接着,主机就会以低速模式给低速设备发送令牌包和数据包等。

      PING令牌包与OUT令牌包具有一样的结构,但是PING令牌包后并不发送数据,而是等待设备返回ACK或NAK,以判断设备是否能传送数据。在USB1.1中,是没有PING令牌包的。只有在USB2.0高速环境下才会使用PING令牌包,它只被使用在批量传输和控制传输的输出事务中。只用使用OUT令牌包发送数据时,不管设备是否有空间接收数据,都会在OUT令牌包之后跟着发送一个数据包,如果设备没有空间接收数据,就返回一个NAK。这样的结果就是浪费了总线带宽。在高速设备中增加了这个PING机制,主机先用PING令牌包试试设备是否有空间接收数据,而不是先把数据发送出去。在全速模式下,有时会遇到一个有趣的现象,就是下位机程序慢了一点点处理完数据,结果传输速度却下降了很多。这就是OUT过程直接发送数据导致的,也就是说,虽然程序值慢了一点,但是却丢弃了整个数据包。

      SPLIT令牌包时高速事务分裂令牌包,通知集线器将高速数据包转化为全速或者低速数据包发送给其下面的端口。ERR握手包是在分裂事务中表示错误使用。由于高速分裂事务过程比较复杂,主要属于集线器的功能。

    3. 如何处理数据包

      这么多类型的包以及传输过程,一般的USB接口芯片会完成如CRC校验、位填充、PID识别、数据包切换、握手等协议的处理。

      当USB接口芯片正确接收到数据时,如果有空间保存,则它将数据保存并返回ACK,同时,设置一个标志表示已经正确接收到数据;如果没有空间保存数据,则自动会返回NAK。收到输入请求时,如果有数据需要发送,则发送数据,并等待接收ACK。只有当数据成功发送出去(即接收到ACK)之后,它才设置标志,表示数据已成功发送;如果无数据需要发送,则它自动返回NAK。通常指需要根据芯片提供的一些标志,准备要发送的数据到端点,或者从端点读取接收到的数据即可。所要发送和接收的数据是指数据包中的数据,至于同步域、包标识、地址、端点、CRC等是看不到的。

  • USB的四种传输类型

    1. USB事务

      事务(transaction)通常由两个或三个包组成:令牌包、数据包和握手包

      令牌包用来启动一个事务,总是有主机发送;

      数据包传送数据,可以从主机到设备,也可以从设备到主机,方向有令牌包来指定;

      握手包的发送者通常为数据接收者,当数据接收正确后,发送握手包。设备也可以使用NAK握手包来表示数据还未准备好。

      USB协议规定了4种传输类型:批量传输、等待传输(同步传输)、中断传输和控制传输。其中,批量传输、等待传输、中断传输每传输一次数据都是一个事务;控制传输包含按个过程:建立过程、数据过程、状态过程。建立过程和状态过程分别是一个事务,数据过程可能包含多个事务。

    2. 批量传输

      批量传输使用批量事务(bulk transaction)传输数据。一次批量事务有三个阶段:令牌包阶段、数据包阶段和握手阶段。

      批量传输分为批量读和批量写,批量读使用批量输入事务,批量写使用批量输出事务。批量传输没有规定数据包中数据的意义和结构,具体的数据结构要由设备自己定义。批量传输通常用在数据量大、对数据的实时性要求不高的场合,例如USB打印机、扫描仪、大容量存储设备等。

      批量输出事务

      主机先发出一个OUT令牌包,这个令牌包中包含了设备地址、端点号。然后,在发送一个DATA包(具体是什么类型的DATA包,要看数据切换位),这时地址和端点匹配的设备就会收下这个数据包。然后主机切换到接收模式,等待设备返回握手包。

      设备解码令牌包、数据包都准确无误,并且有足够的缓冲区来保存数据后,就会使用ACK握手包或者NYET握手包来应答主机(只有高速模式才有NYET握手包,它表示本次数据成功接收,但是没有能力接收下一次传输)。如果没有足够的缓冲区来保存数据,那么它就会返回一个NAK握手包,高速主机目前没有缓冲区可用,主机会在稍后的时间重试该批量输出事务。如果设备检测到数据正确,但是端点处于挂起状态,则返回一个STALL握手包。如果设备检测到错误(如CRC检验错误、位填充错误等),则不作任何响应,让主机等待超时。

      批量输入事务

      主机先发出一个IN令牌包,同意,IN令牌包中包含了设备地址和端点号。然后主机切换到接收数据状态,等待设备返回数据。如果设备检测到错误,那么不作任何响应,主机等待超时。如果此时有地址和端点匹配的设备,并且没有检测到错误,则设备做出响应:如果设备有数据需要返回,那么它把一个数据包放到总线上(具体的数据包类型要看数据切换位);如果没有数据需要返回,则它直接使用NAK握手包来响应主机;如果端点处于挂起状态,设备会返回一个STALL握手包。此时如果主机接收到设备发送的数据包并解码正确后,使用ACK握手包应答设备。如果主机检测到错误,则不作任何响应,设备会检测超时。

      在USB协议中不允许主机使用NAK握手包来拒绝接受数据包。主要原因是主机既然没有空间接收数,还给设备发送请求返回数据,就多此一举,浪费资源。

      在USB2.0高速设备中增加了一个PING令牌包,它不发出数据,直接等待设备的握手包。因此PING事务只要令牌包和握手包

      批量事务流程图

    批量输入事务

    批量输出事务

    1. 中断传输

      中断传输是一种保证查询频率的传输。中断端点在端点描述符中要报告它的查询间隔,主机会保证在小于这个时间间隔的范围内安排一次传输。

      中断传输的中断与硬件上的中断是不一样的。它不是由设备主动发出一个中断请求,而是由主机保证在不大于某个时间间隔内安排一次传输。

      中断传输通常用在数据量不大,但是对时间要求比较严格的设备中,例如人机接口设备(HID)中的鼠标、键盘、轨迹球等。中断传输也可以用来不断的检测某个状态,当条件满足后再使用批量传输来传送大量的数据。

      除了在对端点查询的策略上不一样外,中断传输和批量传输的结构基本上是一样的,只是中断传输中没有PING和NYET两种包。

      中断传输使用中断事务(interrupt transaction),中断事务的流程如下:

    中断事务流程图

    1. 等时传输(同步传输)

      同步传输用在数据量大、对实时性要求高的场合,例如音频设备、视频设备等,这些设备对数据延时很敏感。对音频或视频设备来说,对数据的100%正确要求不高,少量数据的错误还是能容忍的,主要是要保证不能停顿;所以同步传输是不保证数据100%正确的。当数据错误时,并不进行重传。因此,同步传输没有应答包。数据是否正确,可以由数据包的CRC校验来确认。对于出错数据的处理有软件来决定。

      同步传输使用同步事务来传输数据,同步事务的流程图如下:

      同步事务流程图

    2. 控制传输

      控制传输分为三个过程:第一个过程是建立过程,第二个过程是可选的数据过程,第三个过程是状态过程。

      建立过程使用一个建立事务。建立事务是一个输出数据的过程,与批量传输的输出事务相比,有几处不一样:首先令牌包不一样,建立过程使用SETUP令牌包;其次是数据包类型不一样,建立过程只能使用DATA0包;最后是握手包不一样,设备只能使用ACK握手包来应答(除非出错了,不应答),而不能使用NAK或STALL来应答,即设备必须要接收建立事务的数据,建立事务的流程图如下:

    建立事务流程图

    数据过程是可选的,即一个控制传输可能没有数据过程。如果有,一个数据过程可以包含一笔或者多笔数据事务。控制传输所使用的数据事务与批量传输中的批量事务时一样的。需要注意的是,在数据过程中,所有的数据事务必须是同一个传输方向的。也就是说在控制读传输中,数据过程中的所有数据事务都必须是输入的;在控制写传输中,数据过程中的所有数据事务都必须是输出的。一旦数据传输方向发送改变,就会认为进入了状态过程。数据过程的第一个数据包必须是DATA1包,然后每次正确传输一个数据包后就在DATA0和DATA1之间交替。

    状态过程也是一笔批量事务,它的传输方向刚好和前面的数据阶段相反,即控制写传输在状态过程使用一个批量输入事务;控制读传输在状态过程使用一个批量输出事务。状态过程只能使用DATA1。

    控制传输的复杂性,是因为它要保证数据传输过程的数据完整性。设备枚举过程中各种描述符的获取以及设置地址、设置配置等,都是通过控制传输来实现的。如下是几种控制传输的实例:

    控制传输实例

    1. 端点类型与传输类型的关系

      一个具体的端点,只能工作在一种传输模式下。通常,把工作在什么模式下的端点就叫做什么端点。例如控制端点、批量端点等。

      端点0是每个USB设备必须具备的默认控制端点,它一上电就存在并且可用。设备的各种描述符以及主机发送的一些命令,都是通过端点0传输的。其他端点是可选的,需要根据具体的设备来决定。非0端点只有在Set Config之后才能使用。

    2. 传输类型与端点支持的最大包长

      每个端点描述符中都规定了端点所支持的最大数据包长。主机每次发送数据包,都不能超过端点的最大包长。

      对于控制传输的端点,低速模式下最大包长固定为8字节,高速模式最大包长固定为64字节。全速模式可在8、16、32、64字节中选择

      对于同步传输的端点,全速模式最大包长上限为1023字节,高速模式下最大包长上限为1024字节,低速模式不支持同步传输。

      对于中断传输的端点,低速模式最大包长上限为8字节,全速模式最大包长上限为64字节,高速模式最大包长上限为1024字节。

      对于批量传输的端点,高速模式固定为512字节,全速模式最大包长可在8、16、32、64字节中选择,低速模式不支持批量传输。

posted @ 2019-07-25 16:51  szhl  阅读(1064)  评论(0编辑  收藏  举报