5. USB协议

https://blog.csdn.net/songze_lee/article/details/77658094

1. USB概述

USB总线属于一种轮询式总线,主机控制端口初始化所有的数据传输。每一总线动作最多传送三个数据包,包括令牌(Token)、数据(Data)、联络(HandShake)。

按照传输前制定好的原则,在每次传送开始时,主机送一个描述传输动作的种类、方向、USB设备地址和终端号的USB数据包,这个数据包通常被称为令牌包(TokenPacket)。USB设备从解码后的数据包的适当位置取出属于自己的数据。数据传输方向不是从主机到设备就是从设备到主机。

在传输开始时,由标志包来标志数据的传输方向,然后发送端开始发送包含信息的数据包或表明没有数据传送。接收端也要相应发送一个握手的数据包表明是否传送成功。发送端和接收端之间的USB数据传输,在主机和设备的端口之间,可视为一个通道。USB中有一个特殊的通道一缺省控制通道,它属于消息通道,设备一启动即存在,从而为设备的设置、状态查询和输入控制信息提供一个入口。

2. USB基本知识普及

1. 端点: 位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有惟一的确定地址,有不同的传输特性(如输入端点、输出端点、配置端点、批量传输端点) 

2. 帧: 时间概念,在USB中,一帧就是1MS,它是一个独立的单元,包含了一系列总线动作,USB将1帧分为好几份,每一份中是一个USB的传输动作。 

3. upstream、downstream(上行、下行):设备到主机为上行,主机到设备为下行

4. USB传输线:vcc、gnd、D+、D- 差分线。3.3V电压

5. 传送方式: 数据在usb线里由地位到高位传送

6. USB的数据格式:USB数据是由二进制数字串构成的,首先数字串构成(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)

3. USB的域

7种域

1、同步域(SYNC),八位,值固定为0000 0001,用于本地时钟与输入同步

2、标识域(PID),由四位标识符+四位标识符反码构成,表明包的类型和格式,这是一个很重要的部分,这里可以计算出,USB的标识码有16种,具体分类请看问题五。

3、地址域(ADDR):七位地址,代表了设备在主机上的地址,地址000 0000被命名为零地址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址,由此可以知道为什么一个USB主机只能接127个设备的原因。

4、端点域(ENDP),四位,由此可知一个USB设备有的端点数量最大为16个。

5、帧号域(FRAM),11位,每一个帧都有一个特定的帧号,帧号域最大容量0x800,对于同步传输有重要意义(同步传输为四种传输类型之一,请看下面)。

6、数据域(DATA):长度为0~1023字节,在不同的传输类型中,数据域的长度各不相同,但必须为整数个字节的长度

7、校验域(CRC):对令牌包和数据包(对于包的分类请看下面)中非PID域进行校验的一种方法,CRC校验在通讯中应用很泛,是一种很好的校验方法,至于具体的校验方法这里就不多说,请查阅相关资料,只须注意CRC码的除法是模2运算,不同于10进制中的除法。


关于PID标识域名

        令牌包

        0x01:输出(OUT)启动一个方向为主机到设备的传输,并包含了设备地址和标号。

        0x09:输入(IN) 启动一个方向为设备到主机的传输,并包含了设备地址和标号。

        0x05:帧起始(SOF)表示一个帧的开始,并且包含了相应的帧号。

        0x0d:设置(SETUP)启动一个控制传输,用于主机对设备的初始化。

        数据包 :

        0x03:偶数据包(DATA0)。

        0x0b:奇数据包(DATA1)。

        握手包:

        0x02:确认接收到无误的数据包(ACK)。

        0x0a:无效,接收(发送)端正在忙而无法接收(发送)信息。

        0x0e:错误,端点被禁止或不支持控制管道请求。

        特殊包0x0C前导,用于启动下行端口的低速设备的数据传输。

4. USB的包

包:由域构成的包有四种类型,分别是令牌包、数据包、握手包和特殊包,前面三种是重要的包,不同的包的域结构不同,介绍如下

1、令牌包:可分为输入包、输出包、设置包和帧起始包(注意这里的输入包是用于设置输入命令的,输出包是用来设置输出命令的,而不是放据数的)其中输入包、输出包和设置包的格式都是一样的:

SYNC+PID+ADDR+ENDP+CRC5(五位的校验码)

帧起始包的格式:

SYNC+PID+11位FRAM+CRC5(五位的校验码)

2、数据包:分为DATA0包和DATA1包,当USB发送数据的时候,当一次发送的数据长度大于相应端点的容量时,就需要把数据包分为好几个包,分批发送,DATA0包和DATA1包交替发送,即如果第一个数据包是 DATA0,那第二个数据包就是DATA1。但也有例外情况,在同步传输中(四类传输类型中之一),所有的数据包都是为DATA0,格式如下:

SYNC+PID+0~1023字节+CRC16

3、握手包:结构最为简单的包,格式如下

SYNC+PID

5. USB的事物

        分别有IN、OUT和SETUP三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成,这里用阶段的意思是因为这些包的发送是有一定的时间先后顺序的,事务的三个阶段如下:

        1、令牌包阶段:启动一个输入、输出或设置的事务。

        2、数据包阶段:按输入、输出发送相应的数据。

        3、握手包阶段:返回数据接收情况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。

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

       5. 1、 IN事务:

        令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;

        数据包阶段——设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)。

        1) 设备端点正常:设备往主机里面发出数据包(DATA0与DATA1交替);

        2) 设备正在忙:无法往主机发出数据包就发送NAK无效包,IN事务提前结束,到了下一个IN事务才继续;

        3) 相应设备端点被禁止:发送错误包STALL包,事务也就提前结束了,总线进入空闲状态。

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

        5.2、 OUT事务:

        令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;

        数据包阶段——比较简单,就是主机会往设备送数据,DATA0与DATA1交替

        握手包阶段——设备根据情况会作出三种反应

        1) 设备端点接收正确,设备给主机返回ACK,通知主机可以发送新的数据,如果数据包发生了CRC校验错误,将不返回任何握手信息;

        2) 设备正在忙,无法给主机返回ACK,就发送NAK无效包,通知主机再次发送数据;

        3) 相应设备端点被禁止,发送错误包STALL包,事务提前结束,总线直接进入空闲状态。

       5.3、SETUT事务:

        令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;

        数据包阶段——比较简单,就是主机往设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令,详见2.4。

        握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)。

6. USB的四种传输

        USB系统中的数据传输,宏观看是在HOST和USB功能设备之间进行。微观看是在应用软件的Buffer和USB功能设备的端点之间进行。一般来说端点都有Buffer,可以认为USB通讯就是应用软件Buffer和设备端点Buffer之间的数据交换,交换的通道称为管道。应用软件通过和设备之间的数据交换来完成设备控制和数据传输。通常需要多个管道来完成数据交换,因为同一管道只支持一种类型的数据传输。用在一起来对设备进行控制的若干管道称为设备的接口,这就是端点、管道和接口的关系。

        USB 采用“令牌包”-“数据包”-“握手包”的传输机制,在令牌包中指定数据包去向或者来源的设备地址和端点(Endpoint),从而保证了只有一个设备对被广播的数据包/令牌包作出响应。握手包表示了传输的成功与否。

        USB 采用轮询的广播机制传输数据,所有的传输都由主机发起,任何时刻整个 USB 体系内仅允许一个数据包的传输,即不同物理传输线上看到的数据包都是同一被广播的数据包。

        传输由OUT、IN和SETUP事务构成,传输有四种类型,中断传输、批量传输、同步传输、控制传输,其中中断传输和批量传输的结构一样,同步传输有最简单的结构,而控制传输是最重要的也是最复杂的传输。

6. 1.  控制传输:

        控制传输是一种可靠的双向传输,一次控制传输可分为三个阶段。

        第一阶段为从HOST到Device的SETUP事务传输,这个阶段指定了此次控制传输的请求类型;

        第二阶段为数据阶段,也有些请求没有数据阶段;第三阶段为状态阶段,通过一次IN/OUT 传输表明请求是否成功完成。

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

         其他三种传输类型都没有格式定义。

         控制传输对于最大包长度有固定的要求。对于高速设备该值为 64Byte;对于低速设备该值为 8;全速设备可以是 8或 16或 32或 64。

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

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

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

      控制传输在访问总线时也受到一些限制,如:

a. 高速端点的控制传输不能占用超过 20%的微帧,全速和低速的则不能超过 10%。 

b. 在一帧内如果有多余的未用时间,并且没有同步和中断传输,可以用来进行控制传输。

6. 2.  中断传输:

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

        中断传输的延迟有保证,但并非实时传输,它是一种延迟有限的可靠传输,支持错误重传

        对于高速/全速/低速端点,最大包长度分别可以达到1024/64/8 Bytes。

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

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

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

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

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

6. 3.  批量传输:

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

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

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

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

6. 4.  同步传输:

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

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

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

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

          分离传输对于USB 设备来说是透明的、不可见的。

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

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


USB的最小单元是“域”,由“域”构成了“包”,在由“包”构成了“事务”,最后由“事务”构成了“传输”,在应用层面,我们看到的只是传输,所以USB协议栈就需要完成传输以下的所有事情。这对标准的USB协议栈提出了最基本的要求。 

8.枚举

8.1 枚举时USB的状态

当USB设备插上主机时,主机就通过一系列的动作来对设备进行枚举配置(配置是属于枚举的一个态,态表示暂时的状态),这些态如下:

1、接入态(Attached):设备接入主机后,主机通过检测信号线上的电平变化来发现设备的接入;

2、供电态(Powered):就是给设备供电,分为设备接入时的默认供电值,配置阶段后的供电值(按数据中要求的最大值,可通过编程设置);

3、缺省态(Default):USB在被配置之前,通过缺省地址0与主机进行通信;

4、地址态(Address):经过了配置,USB设备被复位后,就可以按主机分配给它的唯一地址来与主机通信,这种状态就是地址态;

5、配置态(Configured):通过各种标准的USB请求命令来获取设备的各种信息,并对设备的某些信息进行改变或设置。

6、挂起态(Suspended):总线供电设备在3ms内没有总线操作,即USB总线处于空闲状态的话,该设备就要自动进入挂起状态,在进入挂起状态后,总的电流功耗不超过280uA。

8.2 枚举过程

1、用户将一个USB设备插入USB端口,主机为端口供电,设备此时处于上电状态。主机检测设备。集线器使用中断通道将事件报告给主机。

2、主机发送Get_Port_Status(读端口状态)请求,以获取更多的设备信息。返回的消息告诉主机该设备是什么时候连接的。集线器检测设备是低速运行还是高速运行,并将此信息送给主机,这是对Get_Port_Status请求的响应。

3、主机发送Set_Port_Feature(写端口状态)请求给集线器,要求它复位端口,请求集线器来重新设置端口。集线器使设备的USB数据线处于重启(RESET)状态至少10ms。

4、主机使用Chirp K信号来了解全速设备是否支持高速运行。

5、主机发送另一个Get_Port_Status请求,确定设备是否已经从复位状态退出。返回的数据有一位表示设备仍然处于重启状态。当集线器释放了重启状态,设备此时处于缺省状态,且已准备好在零端点通过缺省通道响应主机控制传输。缺省地址为00h,设备能从总线获取高达100mA的电流。

6、集线器检测设备速度

        集线器通过测定哪根信号线(D+或D-)在空闲时有更高的电压来检测设备是低速设备还是全速设备。全速和高速设备D+有上拉电阻,低速设备D-有上拉电阻。

7、获取最大数据包长度

主机向address 0发送Get_Device_Deor(读设备描述符)报文,以取得缺省控制管道所支持的最大数据包长度。并在有限的时间内等待USB设备的响应。该长度包含在设备描述符的bMaxPacketSize0字段中,其地址偏移量为7,所以这时主机只需读取该描述符的前8个字节。注意,主机一次只能枚举一个USB设备,所以同一时刻只能有一个USB设备使用缺省地址0。

例:主机向设备发送一个八字节请求:80 06 00 01 00 00 40 00,设备接收到请求后产生一个中断,我们可以通过读中断寄存器知道中断源,并且可以加读最后状态寄存器来确定第一个接到的包是否为一个Setup包。当控制器处理程序判断出它是一个Get_descriptor请求时,把设备描述符的前16个字节发送到端点0缓冲区中。剩下的2个字节描述符第一次请求时不再发送。

8、主机分配一个新的地址给设备

        主机通过发送一个Set_Address请求来分配一个唯一的地址给设备。设备读取这个请求,返回一个确认,并保存新的地址。从此开始所有通信都使用这个新地址。

        例:当主机收到正确的前16字节描述符后,会给设备分配一个地址,我的PC分配的地址为:0x03(这个要看你的机子当时的USB接口设备数目而定) Set_Address 请求所发送的数据为:00 05 03 00 00 00 00 00,其中的03就表示主机为设备分配的地址为0x03,在以后的通信里设备就只对0x03地址作出应答。当设备产生一个接收中断后,根据所分配的地址设置设备的地址寄存器相应位。

9、主机向新地址重新发送Get_Device_Deor命令,此次读取其设备描述符的全部字段,以了解该设备的总体信息,如VID,PID。

例:主机发送设备描述符标准请求Get_descriptor:80 06 00 01 00 00 12 00,此次将要求把18个字节全部发送完。所以主机要分两次来读取。第一次读取16个字节,第二次读取两个字节,最后主机发送0表示发送完毕的应答。

10、主机向设备循环发送Get_Device_Configuration命令,要求USB设备回答,以读取全部配置信息。

11、主机发送Get_Device_String命令,获得字符集描述(unicode),比如产商、产品描述、型号等等。此时主机将会弹出窗口,展示发现新设备的信息,产商、产品描述、型号等。

        根据Device_Deor和Device_Configuration应答,PC判断是否能够提供USB的Driver,一般win2k能提供几大类的设备,如游戏操作杆、存储、打印机、扫描仪等,操作就在后台运行。但是Win98却不可以,所以在此时将会弹出对话框,索要USB的Driver。

12、主机分配并加载设备驱动程序,这时就可能作应用中的数据传输了。

13、主机发送Set_Configuration(x)(写配置)命令请求为该设备选择一个合适的配置(x代表非0的配置值)。如果配置成功,USB设备进入“配置”状态,并可以和客户软件进行数据传输。此时,常规的USB完成了其必须进行的配置和连接工作,至此设备应当可以开始使用。不过,USB协议还提供了一些用户可选的协议,设备如果不应答,也不会出错,但是会影响到系统的功能。

14、主机为复合设备接口分配驱动程序。如果集线器检测到有过流现象,或者主机要求集线器关闭电源,则USB总线切断设备供电电源。在这种情况下,设备与主机无法通信,但设备处于连接状态。  

8. USB的描述符

Descriptor是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的。它的作用就是给主机传递信息,从而让主机知道设备具有什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机确定了这些信息之后,设备才能真正开始工作,所以描述符也是十分重要的部分,标准的描述符有5种,USB为这些描述符定义了编号:

        1——设备描述符

        2——配置描述符

        3——字符描述符

        4——接口描述符

        5——端点描述符

        上面的描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。这些描述符是用一定的字段构成的,分别如下说明:

   1、设备描述符

struct _DEVICE_DEscriptOR_STRUCT{

    BYTE bLength;                          //设备描述符的字节数大小,为0x12

    BYTE bDescriptorType;          //描述符类型编号,为0x01

    WORD bcdUSB;                       //USB版本号

    BYTE bDeviceClass;  //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型

                                            //0x00不是在设备描述符中定义的,如HID

    BYTE bDeviceSubClass;   //usb分配的子类代码,同上,值由USB规定和分配的

    BYTE bDeviceProtocl;             //USB分配的设备协议代码,同上

    BYTE bMaxPacketSize0;        //端点0的最大包的大小

    WORD idVendor;                      //厂商编号

    WORD idProduct;                     //产品编号

    WORD bcdDevice;                   //设备出厂编号

    BYTE iManufacturer;             //描述厂商字符串的索引

    BYTE iProduct;                      //描述产品字符串的索引

    BYTE iSerialNumber;          //描述设备序列号字符串的索引

    BYTE bNumConfiguration; //可能的配置数量

}

  2、配置描述符

struct _CONFIGURATION_DEscriptOR_STRUCT{

    BYTE bLength;                      //设备描述符的字节数大小,为0x12

    BYTE bDescriptorType;       //描述符类型编号,为0x01

    WORD wTotalLength;          //配置所返回的所有数量的大小

    BYTE bNumInterface;          //此配置所支持的接口数量

    BYTE bConfigurationVale;  //Set_Configuration命令需要的参数值

    BYTE iConfiguration;           //描述该配置的字符串的索引值

    BYTE bmAttribute;                  //供电模式的选择

    BYTE MaxPower;                   //设备从总线提取的最大电流

}

3、字符描述符

struct _STRING_DEscriptOR_STRUCT{

    BYTE bLength;                              //设备描述符的字节数大小,为0x12

    BYTE bDescriptorType;               //描述符类型编号,为0x01

    BYTE SomeDescriptor[36];         //UNICODE编码的字符串

}

        4、接口描述符

struct _INTERFACE_DEscriptOR_STRUCT{

    BYTE bLength;                      //设备描述符的字节数大小,为0x12

    BYTE bDescriptorType;      //描述符类型编号,为0x01

    BYTE bInterfaceNunber;     //接口的编号

    BYTE bAlternateSetting;        //备用的接口描述符编号

    BYTE bNumEndpoints;        //该接口使用端点数,不包括端点0

    BYTE bInterfaceClass;          //接口类型

    BYTE bInterfaceSubClass;    //接口子类型

    BYTE bInterfaceProtocol;    //接口所遵循的协议

    BYTE iInterface;                    //描述该接口的字符串索引值

}

        5、端点描述符

struct _ENDPOIN_DEscriptOR_STRUCT{

    BYTE bLength;                        //设备描述符的字节数大小,为0x12

    BYTE bDescriptorType;          //描述符类型编号,为0x01

    BYTE bEndpointAddress;      //端点地址及输入输出属性

    BYTE bmAttribute;                   //端点的传输类型属性

    WORD wMaxPacketSize;       //端点收、发最大包的大小

    BYTE bInterval;                        //主机查询端点的时间间隔

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 端点 端点是一个USB设备唯一可以确认的部分,他是主机和设备之间的通信流的重点。每一个USB逻辑设备都包含了一个相...
    Joe_HUST阅读 1,664评论 0 1
  • (转)USB入门系列之一----基本知识luckygirl 发表于 2009-7-11 23:43:00USB 基...
    spfanlost阅读 1,703评论 0 2
  • 内容原创,未经本人同意请勿转载。联系本人:jianshu_kevin@126.com PIPE usb通信的最基本...
    kevin_007阅读 3,180评论 1 4
  • 内容原创,未经本人同意请勿转载。联系本人:jianshu_kevin@126.com 初次接触USB的同学,可能会...
    kevin_007阅读 8,544评论 2 11
  • Linux usb system(descriptor) 为了更好地描述USB设备的特征,USB提出了设备架构的概...
    Creator_Ly阅读 1,245评论 0 4