USB端口数据分析

来源:互联网 发布:java按键监听器 编辑:程序博客网 时间:2024/06/06 00:50

Device  Phase  Data                      Description       Cmd.Phase.Ofs(rep)

------  -----  ------------------------  ----------------  ------------------

  18.0  CTL    80 06 00 01  00 00 12 00  GET DESCRIPTOR           1.1.0        

  18.0  IN     12 01 10 01  00 00 00 08  ........                 1.2.0        

               3c 41 03 20  00 02 01 02  <A. ....                 1.2.8        

               00 01                     ..                       1.2.16       

  18.0  CTL    80 06 00 02  00 00 09 00  GET DESCRIPTOR           2.1.0        

  18.0  IN     09 02 22 00  01 01 04 a0  ..".....                 2.2.0        

               23                        #                        2.2.8        

  18.0  CTL    80 06 00 02  00 00 22 00  GET DESCRIPTOR           3.1.0        

  18.0  IN     09 02 22 00  01 01 04 a0  ..".....                 3.2.0        

               23 09 04 00  00 01 03 01  #.......                 3.2.8        

               01 05 09 21  10 01 00 01  ...!....                 3.2.16       

               22 41 00 07  05 81 03 08  "A......                 3.2.24       

  18.0  CTL    00 09 01 00  00 00 00 00  SET CONFIG               4.1.0        

  18.0  CTL    21 0a 00 00  00 00 00 00  SET IDLE                 5.1.0        

  18.0  CTL    81 06 00 22  00 00 81 00  GET DESCRIPTOR           6.1.0        

  18.0  IN     05 01 09 05  a1 01 05 07  ........                 6.2.0        

               19 e0 29 e7  15 00 25 01  ..)...%.                 6.2.8        

               75 01 95 08  81 02 95 01  u.......                 6.2.16       

               75 08 81 01  95 03 75 01  u.....u.                 6.2.24       

  18.1  IN     00 00 d0 00  00 00 00 00  ........                 7.1.0        

  18.1  IN     00 00 c5 00  00 00 00 00  ........                 8.1.0        

  18.1  IN     00 00 b8 00  00 00 00 00  ........                 9.1.0        

  18.1  IN     00 00 d3 00  00 00 00 00  ........                10.1.0(14)    

  18.1  IN     00 00 c0 00  00 00 00 00  ........                11.1.0(14)    

  18.1  IN     00 00 b3 00  00 00 00 00  ........                12.1.0(14)      

1.  收到主控器的获取 设备描述符 配置包

 目的只有一个,就是获取插入的USB属性,以便加载合适的驱动程序

18.0  CTL    80 06 00 01  00 00 12 00  GET DESCRIPTOR           1.1.0   

80:bmReuestType  标准请求字   D7 D6 D5 D4 D3 D2 D1 D0

 1  0  0  0  0  0  0  0

 0  0  1  0  0  0  0  1   21

D7位是表示后面传送数据的方向位。1

D7等于0时,表示后面的数据是从主控器发送到USB设备。在PC里,就是从PC机发送到USB的设备。

D7等于1时,表示后面的数据是从USB设备发送到主控器。在PC里,就是从USB设备发送到USB备。

 

D6-D5位是请求主分类型0 0

是表示标准的请求1 是表示类别的请求,2 是表示厂商的请求, 3 是保留

 

D4-D0位是表求接收这个包的接口。是表示USB设备接收,1 是表示接口接收,2 是表示端点接收,3 是表示其它接收,不知道的。4-3是保留。0 0 0 0 

 

06bRequest  本描述符的请求类型 就是后面发送的数据是什么样的东西。由于USB里有很多配置信息,比如获取设备描述符,又有设置USB地址等等,就是通过这个字节来区分的。USB协议里查找表9-4,就可看到如下的编码:

GET_STATUS        0       CLEAR_FEATURE     1    Reserved for future use   2   SET_FEATURE            3       Reserved for future use     4

SET_ADDRESS      5      GET_DESCRIPTOR   6    SET_DESCRIPTOR         7   GET_CONFIGURATION   8    SET_CONFIGURATION    9

GET_INTERFACE    10      SET_INTERFACE    11        SYNCH_FRAME     12

06也就是主控器想读取USB设备的描述符,但还不知道是什么描述符的内容。

 

00 01wValue是根据不同的请求而设置不同的值。一般就是传送参数给设备标明这是什么请求。在上面GET_DESCRIPTOR获取设备描述符里,它的值是00 01。在GET_DESCRIPTOR里这个字段的低字节表示描述符的索引,高字节表示描述符的类型。高字节的类型如下:

DEVICE                  1     CONFIGURATION          2   STRING                   3   INTERFACE                4    ENDPOINT                5

DEVICE_QUALIFIER         6     OTHER_SPEED_CONFIGURATION             7    INTERFACE_POWER1                  8

wValue值在这里的高字节是01,那么它就是设备描述符了。低字节是00,那么它就是表示从偏移地址0开始读取设备描述符。由于在配置描述符里有很多配置,所以低字节在那里就可以用来识别获取同样类型的描述符不同的配置。

 

00 00wIndex是根据不同的请求而设置不同的值。一般用来说明端点号或者说明接口标识。在获取描述符里,设置为0,或者是语言ID在这个发送的描述符里,它是设置为00 00

 

12 00 :wLength是根据请求来决定下一阶段发送数据的长度。前面请求第一个字节里,已经说明下一阶段数据传送的方向,这里说明了传送数据的长度。不管是发送数据,还是接收数据,都不要超过这个数据长度,否则主机会出问题,或者设备有问题。在这个获取设备描述里,这边是 12 00 (网上它的长度是40 00按小端格式去解释,就是64个字节

 

收到主控器的获取设备描述符的数据,这里就解释怎么样发送回应数据给主控器。

先从USB协议里找到标准设备的定义,我把它用C语言定义如下:

typedef struct _USB_DEVICE_DESCRIPTOR {

 BYTE bLength;

 BYTE bDescriptorType;

 WORD bcdUSB;

 BYTE bDeviceClass;        00

 BYTE bDeviceSubClass;    00

 BYTE bDeviceProtocol;      00

 BYTE bMaxPacketSize0;     08

 WORD idVendor;    3c 41 

 WORD idProduct;   03 20

 WORD bcdDevice;  00 02

 BYTE iManufacturer;  01

 BYTE iProduct;   02

 BYTE iSerialNumber;   00 

 BYTE bNumConfigurations;    01

} USB_DEVICE_DESCRIPTOR;

返回给主控器的数据结构就是上面的内容,只要把上面的结构填写合适的内容,就可以发送回去给主控器。在我的USB设备里,我把它填写如下的数据:

12 01 10 01  00 00 00 08   3c 41 03 20  00 02 01 02   00 01 

12bLength是本结构的数据长度,这样可以方便以后兼容不同的版本协议。因为不同的结构是不同的长度,这样就可以区分不同的协议了。比如有一天想添加一个字段,那么它的长度就会改变,这时就可以根据不同的长度进行解释不同的协议了。这次返回的结构长度是0x12,也就是18个字节,它的长度是从bLength度开始,也就是说是完全整个结构的长度。

 

01bDescriptorType是描述符的类型。它的定义跟主控器发下来描述符的类型是一样的,如下:

DEVICE      1   CONFIGURATION          2    STRING     3   INTERFACE   4     ENDPOINT    5

DEVICE_QUALIFIER    6     OTHER_SPEED_CONFIGURATION    7     INTERFACE_POWER1                8

由于返回的是设备描述符,所以就选择了1,也就是包里显示的第二个字节01。用这个类型来区分不同的描述符

10 01 :bcdUSB是USB发布的协议版本。也就是本设备能适用于那种协议,目前USB主要有两个版本,一个是1.10,一个是2.10版本。在本设备里,采用了1.10的协议版本。由于这个字段是采用BCD编码,所以1.10的表示为0x0110的格式,按小端格式输出来,就变成10 01的显示了。

00bDeviceClass设备分类。当它的值是0时,表示所有接口在配置描述符里,并且所有接口是独立的。当它的值是1FEH时,表示不同的接口关联的。当它的值是FFH时,它是厂商自己定义的。在这个设备里,是定义为0

 

00bDeviceSubClass是设备子分类码。当前面的bDeviceClass值是0时,这里一定要设置为0。其它就跟据USB-IF组织定义的编码。


00bDeviceProtocol是设备使用的协议。如果使用USB-IF组织定义的协议,就需要设置这里的值。如果不使用,就直接设置为0。如果厂商自己定义的可以设置为FFH

以上三个值,在本设备里全部设置为0

 

08:bMaxPacketSize0是端点0收发最大的包大小。仅允许设置8163264中的任何一个大小。

3c 41 :idVendor是厂商标识。由USB-IF分配的编码。0x413c(在这里使用0x8000(12 01 10 01  00 00 00 40  00 80 00 80 00 01 04 2C 4A 01 )

03 20idProduct是厂商定义的产品标识。由厂家和产品标识,就可以让操作系统加载不同的驱动程序。

00 02bcdDevice是用BCD表示的设备发布的版本号。这里是2.00

01:iManufacturer是厂商字符串的偏移值。这值主要说明了它在字符串描述符(这里可能是要结合)里的偏移位置。如果它设置为0,表示没有厂商字符串。在这里是0x04,就是从字符串描述符开始位置算起第4个字节位置读取字符串。

 

02iProduct是产品字符串的偏移值。这值主要说明了它在字符串描述符里的偏移位置。如果它设置为0,表示没有产品字符串。在这里是0x02,就是从字符串描述符开始位置算起第02个字节位置读取字符串。

 

00:iSerialNumber是序列号字符串的偏移值。这值主要说明了它在字符串描述符里的偏移位置。如果它设置为0,表示没有序列号字符串。在这里是0x4A,就是从字符串描述符开始位置算起第4A个字节位置读取字符串。所有字符串,都是采有UNICODE编码。

 

01bNumConfigurations是配置描述符的个数。在这里只使用了一个配置,所以设置为1


2.收到 配置描述符 配置包

  80 06 00 02  00 00 09 00

根据USB协议可以知道,这是一个配置描述符的包,也就是让USB设备发送本设备有多少个配置方式给主控器。由于USB的设备是多种多样,满足不同的用户需要的。比如鼠标和键盘,就是不同的设备了。还有MP3播放器,还有各种数码相机等等,都是不一样的设备了。就可以通过下面的方式来说明这个配置有多少种方式,主要是通讯的方式。

 

这里的00 02 表示主控器要获取配置描述符  09 00 表示下一次要发送的配置描述符的大小,前面的80表示数据放向(usbpc机)

 

 09 02 22 00  01 01 04 a0   23       

配置描述符定义了设备的配置信息,一个设备可以有多个配置描述符  

typedef struct _USB_CONFIGURATION_DESCRIPTOR_

{

    BYTE      bLength,

    BYTE      bDescriptorType,

    WORD    wTotalLength,

    BYTE      bNumInterfaces,

    BYTE      bConfigurationValue,

    BYTE      iConfiguration,

    BYTE      bmAttributes,

    BYTE      MaxPower

}USB_CONFIGURATION_DESCRIPTOR;      

02bDescriptorType应该为2,即是一个9字节长的配置描述符。 

22 00:wTotalLength域为该 配置描述符 长度加上该配置内所有  接口和端点描述符  长度的总和。通常,主机在发出一个GET_DESCRIPTOR请求并正确接收到9字节长的配置描述符后,就会再发出一个GET_DESCRIPTOR请求并指定这个总长度。第二个请求把这个大联合描述符传输回来。

 

 3. 获取USB全部属性80 06 00 02  00 00 22 00  GET DESCRIPTOR           3.1.0      

  

 09 02 22 00  01 01 04 a0  ..".....                 3.2.0        

               23 09 04 00  00 01 03 01  #.......                 3.2.8        

               01 05 09 21  10 01 00 01  ...!....                 3.2.16       

               22 41 00 07  05 81 03 08  "A...

01bNumInterfaces指出该配置有多少个接口。

01bConfigurationValue域是该配置的索引值。

04iConfiguration域是一个可选的串描述符索引,指向描述该配置的Unicode字符串。此值为0表明该配置没有串描述符。

iConfiguration是说明配置的字符的偏移值。这里是0

A0bmAttributes字节包含描述该配置中设备电源和其他特性的位掩码。

bmAttributes是配置特性,D7位保留。D6位是说明是否自供电。D5位是否支持远程唤醒。D4D0是保留,设置为0

23MaxPower域中指出要从USB总线上获取的最大电流量。

4.   收到 设置描述符 包

 00 09 01 00  00 00 00 00  SET CONFIG    

结合(01:iManufacturer是厂商字符串的偏移值。这值主要说明了它在字符串描述符里的偏移位置。如果它设置为0,表示没有厂商字符串。在这里是0x04,就是从字符串描述符开始位置算起第4个字节位置读取字符串。

 

4.  收到设置空闲描述符包

21 0A 00 00 00 00 00 00

收到这个描述符,就表明设备在空闲状态

5.   收到HID的报告描述符包

 81 06 00 22  00 00 81 00  

剩下和c#上位机再说吧

 

1 0
原创粉丝点击