usb 2.0 spec. http://www.usb.org/developers/docs/usb20_docs/usb_20_042814.zip
解開他,其中有一份 usb_20.pdf 是我們要看的。 請跳到第九章,USB Device Framework。
當你接好usb分析儀之後,將client device 插上host 端。 開始以下的紀錄。
得到的第一個log ...
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
[Standard Device Requests]
CTL 80 06 00 01 00 00 12 00
CTL 表示control 封包。
每個封包以8bytes 為一個單位,像上面的 80 就是 一個單位,你在 spec.
Table 9-2. Format of Setup Data 這個表中,第三欄,Size 他寫1 就是指這個。所以你知道,
這個表中
offset 0 就是指 80 是 BYTE 0, 它是用來表示 bmRequestType 的,只佔Size 1, 也就是說,只要看
80 即可,後面的06 是下一個欄位, 也就是 BYTE1 bRequest 的,他也只占siez 1, 且是看值
來決定屬性,不像 80 是要看bitmap 的。
好,那 80 到底代表甚麼? 二進位是 1000 0000 , 去找 Table 9-3. Standard Device Requests 這個
表
你看到 10000000B,在最左邊,先不要管那個B,你看第二個row 和 第三個row 都是
10000000 ,所以繼續往右看,bRequest 有可能是 GET_CONFIGURATION or GET_DESCRIPTOR。 所以,剛剛那個 06 就是再看,到底是 哪種。 下面有個表
在講bRequest 的....
所以阿,06 就是 十進位的6 ,表中就是 GET_DESCRIPTOR。
好 回顧一下一開始拿到的raw data 80 06 00 01 00 00 12 00。我們看了 80 06 了。
接下來 還有 00 01 00 00 12 00 沒看。 回去 Table 9-2. Format of Setup Data 。
你知道 vValue , vIndex, vLength 都是 size 2. 也就是說,
wValue : 00 01。
wIndex : 00 00。
wLength : 12 00。
而同時對照 Table 9-3. Standard Device Requests。 我們現在看的是 第三行 GET_DESCRIPTOR。
它右邊有寫。
wValue 拿來當作 Descriptor Type and Descriptor Index
所以你再看 Table 9-5. Descriptor Types
我們是 00 01, 十進位就是 1 ,所以是 DEVICE。
一樣的,wIndex 是當作 Zero or Language ID。非0 的話,就是有支援String 型態的 descriptors。
這是optional 的。 所以這邊 00 00 十進位就是0, 也就是它是一般的descriptors, 也就是適用
一般的 descriptors 趴法, 不是直接拿來單字串趴。
最後, wLength : 12 00 表示 Descriptor Length,也就是它要求descriptor 要回給我 12 00 bytes 。
Note:
1.spec. 中有提到,如果你 request 一個 configuration 的 descriptor ,則它會回應你
configuration , all interface , 和 所有interface 下的所有endpoints 的 descriptor 。 一次請求,全部回給
你。
2. 所有的USB device 必須 提供至少一個device descriptor 和最少一個 configuration descriptor.
若沒有,則會回傳 Request Error.
3. 第一個讀到到 configuration descriptor 會帶出 第一個 interface descriptor ,而此interface descriptor 中會再帶出屬於他的 endpoint descriptors。
4. Class - specific or vendor-specific 的 descriptors 會遵循 standard descriptor ,延伸或是修改。
5. 這個standard request 針對此三種 descriptor。 Device , configuration, string。 這三種descriptors 可以被問。
6. bmRequestType 這個欄位,是bitmap 的,其中USB spec 規定MUST 要有的就是 Table 9-3. Standard Device Requests 。 這個表之外的,就是廠商可以自訂。此外如果後面wLength 是 0 的話,第七個bit 的方向性可以忽略。
7. 承6,這個request 可以是針對 device, 一個interface, 或一個特定的endpoint ,這些對象將在 D4,也就是bit 4~ bit 0 這邊指定。 當指定了一個interface or endpoint 後,wIndex 這欄位,就是interface or endpoint 的編號。
D7: Data transfer direction
0 = Host-to-device
1 = Device-to-host
D6...5: Type
0 = Standard
1 = Class
2 = Vendor
3 = Reserved
D4...0: Recipient
0 = Device
1 = Interface
2 = Endpoint
3 = Other
4...31 = Reserved
根據Note 1. 和 3. 我們可以知道以下階層的觀念。
好了,到此,我們終於知道 CTL 80 06 00 01 00 00 12 00 就是跟 client device 說 :
=> 我要 get 你 device 的 descriptor。且回傳0X12 Bytes,也就是 十進位 18bytes。
那,現在你也早就知道,他回你一定會回它有多少configuration 可以用,
所以我們接著看client 的回應。
好了,到此,我們終於知道 CTL 80 06 00 01 00 00 12 00 就是跟 client device 說 :
=> 我要 get 你 device 的 descriptor。且回傳0X12 Bytes,也就是 十進位 18bytes。
那,現在你也早就知道,他回你一定會回它有多少configuration 可以用,
所以我們接著看client 的回應。
---------------------------------------------------------------------------------------------
[Device Descriptor]
IN 12 01 00 02 ef 02 01 40 f0 03 1d 91 32 02 01 02 03 03 ==> 18bytes 如上所示。
要解這段,去找 Table 9-8. Standard Device Descriptor Offset
12 : blength。 等於他之前跟你要求的 12。
01: bDescriptorType。
ef: DeviceClass。 If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate
independently. This value identifies the class definition used for the aggregate
interfaces. 到這裡找 http://www.usb.org/developers/defined_class 你的class code。
在網頁上找到 ef 是 Base Class EFh (Miscellaneous),
02 : bDeviceSubClass 在剛剛找到 Base Class EFh (Miscellaneous), 之中 ,右邊有寫 SubClass 02。
01 : bDeviceProtocol 搭配上面的,找到對應的意義。
Interface Association Descriptor. The usage of this class code triple is defined in the Interface Association Descriptor ECN that is provided on www.usb.org . This class code may only be used in Device Descriptors.
f0 03: idVendor。 http://www.linux-usb.org/usb.ids 但是你要反過來,搜尋, 03f0。
1d 91: idProduct。 這個是廠商自己assigned 的。
....
最後一個
要解這段,去找 Table 9-8. Standard Device Descriptor Offset
12 : blength。 等於他之前跟你要求的 12。
01: bDescriptorType。
ef: DeviceClass。 If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate
independently. This value identifies the class definition used for the aggregate
interfaces. 到這裡找 http://www.usb.org/developers/defined_class 你的class code。
在網頁上找到 ef 是 Base Class EFh (Miscellaneous),
02 : bDeviceSubClass 在剛剛找到 Base Class EFh (Miscellaneous), 之中 ,右邊有寫 SubClass 02。
01 : bDeviceProtocol 搭配上面的,找到對應的意義。
Interface Association Descriptor. The usage of this class code triple is defined in the Interface Association Descriptor ECN that is provided on www.usb.org . This class code may only be used in Device Descriptors.
f0 03: idVendor。 http://www.linux-usb.org/usb.ids 但是你要反過來,搜尋, 03f0。
03f0 Hewlett-Packard
1d 91: idProduct。 這個是廠商自己assigned 的。
....
最後一個
03 : bNumConfigurations。可見得,這個client 有三組configurations 可以讓我們選。
那很自然,host 接下來就會去把這三組configurations 讀過來。
---------------------------------------------------------------------------------------------
[Standard Device Requests]
CTL 80 06 00 02 00 00 09 00
這次又是Get_Descriptor ,但是 02 是要configurations的。 且要求回傳長度 0X09 bytes。
---------------------------------------------------------------------------------------------
IN 09 02 d1 00 05 01 00 a0 fa
這次回的是configuration 的 descriptor,所以要去找 Table 9-10. Standard Configuration Descriptor
09: 09bytes
02: 對應 Descriptor Type,02是CONFIGURATION。
d1 00 : wTotalLength。所以是 0xd1 就是 13*16+1 = 209 bytes。包含這組configuration 所往下連下去的interface, endpoint and class 或 其他vender -specfic 的長度。
05 : bNumInterfaces,有五個interface support。
01 : bConfigurationValue。告訴host, 如果你到時候要用SetConfiguration() 選我這組configuration 的話,你要帶 01 就是 1。
00 : iConfiguration 。這是第 0 個configuration。
a0 : bmAttributes。有支援甚麼。 1010 0000 。 這邊D5 是1,表示有support Remote Wakeup,可喚醒host。
D7: Reserved (set to one)
D6: Self-powered
D5: Remote Wakeup
D4...0: Reserved (reset to zero)
D7 is reserved and must be set to one for
historical reasons.
fa : bMaxPower。此元件所需要的最大power, 單位是2mA。
0xfa = 250。 250*2ma = 500mA。 因為USB 就是最大 500ma,所以它幾乎是全用了。
好了,由這個回應,我們知道,其實這組configuration total 總共有 0xd1 個bytes 要讀取。
所以這次host 又再問一次 configuration,只是這一次,它就會要求client 給d1 長度的資訊回
來,當中就會包含這個configuration 所含的 interface, endpoient, clasee....。 也就是說,
其實上一次host 只是先偷問9bytes, 為的是能先得到,這組configuration 的 總長,因為host不
知道到底新插進來的client , 到底有支援甚麼。
---------------------------------------------------------------------------------------------
CTL 80 06 00 02 00 00 d1 00
再要求一次 02= configurations,但這次要求 d1 長度。
---------------------------------------------------------------------------------------------
IN 09 02 d1 00 05 01 00 a0 fa 09 04 00 00 02 ff ff ff 00 07 05 81 02 00 02 00 07 05 01 02 00 02 00
這次回了一大堆,可是別緊張。 前面 09 02 d1 00 05 01 00 a0 fa 之前已經看過了。
就是 configurations 的內容。 接著看 09 04 00 00 02 ff ff ff 00。
09: 9 bytes.
04: INTERFACE。請去對照interface 的表。Table 9-12. Standard Interface Descriptor
00 : bInterfaceNumber。這是第0個Interface。
00: bAlternateSetting。有幾組可以交替的interface 可以設定,這邊是0。沒得交換。
02 : bNumEndpoints。兩個endpoients 可以使用。
ff: bInterfaceClass。http://www.usb.org/developers/defined_class , 去找ff。ff =Vendor Specific
ff: bInterfaceSubClass。由於上面ff 是vendor specific, subclass填甚麼已經不重要。廠商溝通好即可。
ff:bInterfaceProtocol。 同上
00: iInterface 這是0號interface。
繼續。
IN 09 02 d1 00 05 01 00 a0 fa 09 04 00 00 02 ff ff ff 00 "07 05 81 02 00 02 00" 07 05 01 02 00 02 00
07 05 81 02 00 02 00
07: 長度
05: ENDPOINT (Table 9-5. Descriptor Types),接下來去對,Table 9-13. Standard Endpoint Descriptor。
81: bEndpointAddress。 = 1000 0001
bit7 = 1,In put Endpoint, 0001=1,所以這個是endpoint 1,不是control。
Bit 3...0: The endpoint number
Bit 6...4: Reserved, reset to zero
Bit 7: Direction, ignored for
control endpoints
0 = OUT endpoint
1 = IN endpoint
02: bmAttributes。 0000 0010。
bit5,bit4 = 00。Data endpoint。
bit3,bit2 =00。No Synchronization。
bit1, bit0 =10。Bulk。
00 02: wMaxPacketSize
00: bInterval。這是跟host說,多久polling我一次。
IN 09 02 d1 00 05 01 00 a0 fa 09 04 00 00 02 ff ff ff 00 07 05 81 02 00 02 00 07 05 01 02 00 02 00
再看最後一組
07 05 01 02 00 02 00
幾乎一樣。只差在。
01:bEndpointAddress。 0000 0001。
bit7 =0,OUT put Endpoint, 0001=1,所以這個是endpoint 1。
Bit 3...0: The endpoint number
Bit 6...4: Reserved, reset to zero
Bit 7: Direction, ignored for
control endpoints
0 = OUT endpoint
1 = IN endpoint
沒了。 它全部回完了。 所以你知道,這個device 總共有3組configuration ,而目前我們讀的這組,有一個interface, 這個interface中,有兩個endpoints 一個 IN, 一個OUT。
---------------------------------------------------------------------------------------------
14.0 CTL 00 09 01 00 00 00 00 00
00: bmRequestType。=00000000B。
09 : bRequest。是SET_CONFIGURATION。 去找9.4.7 Set Configuration。
01: Configuration Value= 1,也就是剛剛它有回傳,如果你要設定剛剛那組configuration,
請帶 1 給client,所以看起來,host 要選configuration 1 來用。
後面都是00。 照spec.
設定client 不用回。
---------------------------------------------------------------------------------------------
14.0 CTL 80 06 02 03 09 04 04 00
80
06: GET_DESCRIPTOR
02 03: Descriptor Type and Descriptor Index。你要看成0302。
03 是high byte= descriptor type。
02是low byte=descriptor index。
02=CONFIGURATION,
03= STRING。 表示我接下來要你回string type 的 configuration descriptor 給我。
09 04: Zero or Language ID。check 9.6.7 String。0x0409= English (United States)。
http://www.usb.org/developers/docs/USB_LANGIDs.pdf
04 00: Descriptor Length。回04bytes。
-----------------------------------------------------------------------------------------------------
IN 32 03 48 00
接下來就要看表了。
ASCii 表 http://www.asciitable.com/
32: 2
03:
48:H
00:
-----------------------------------------------------------------------------------------------------
14.0 CTL 80 06 02 03 09 04 32 00
Host 再問一次 02=CONFIGURATION, 03= STRING。,只是這次要求長度是0x32bytes.
-----------------------------------------------------------------------------------------------------
IN 32 03 48 00 50 00 20 00 6c 00 74 00 34 00 32 00 31 00 31 00 20 00 47 00 6f 00 62 00 69 00 20 00
所以她會回 configuration 的內容,用string type 回。
32 03 48 00 這個跟之前的一樣。
IN 32 03 48 00 50 00 20 00 6c 00 74 00 34 00 32 00 31 00 31 00 20 00 47 00 6f 00 62 00 69 00 20 00
32: 2
03:
48:H
00:
50: P
00:
20:
00:
6c:l
.......
......
= 2.H.P. .l.t.4.2.1.1. .G.o.b.i. .
如此,就取得client 的 configuration descriptor。
沒有留言:
張貼留言