2014.4.1

前へ
次へ
ホームページトップへ戻る

CPLD+SIMMを使ってUSBプロトコルの解析を!
VHDLを速習! XC95144XL+16MB・SIMMを使ってUSBプロトコルアナライザを作ってしまいました!
主目的は差し迫った事情からUSBプロトコルの解析をすることだったのですが、その手段として選んだのがコレ!


[第36回]


●Enumeration はじめから終わりまでの記録(4)

このところ記事の進行が遅くて、細切れ状態なのでお話がうまくつながりません。
今回は[第33回]からの続きになります。
[第33回]では自作のCPLD+SIMM回路を使って、WindowsXPパソコンに秋月のPICWRITERをUSB接続したときのEnumerationデータを記録して、それを翻訳解読した結果、そのときホスト(パソコン)から送出されたコマンド(リクエスト)はわずかに9通りしかない、ということを書きました。
そしてそのリクエストの内容について簡単に説明をしました。
リクエストについては今後の説明を進めていくなかでも必要に応じて補足していくつもりです。
そこで、まずはリクエストについてざっと説明が済んだところで、今度はそれに対する装置側の応答について説明をします。
大分時間が経ってしまいましたので、説明を続ける前に、もう一度Enumerationの最初のやり取りのところを見ていただきます。
下は[第31回]にお見せしたリストの終わりの部分(ホストからリクエストが送られ、PICWRITERがそれに応えてデータを送出している部分)です。

0016988 SOF FNO=6DE
0017000 SETUP ADRS=00 ENDP=00 
        DATA0  80 06 00 01 00 00 40 00   GET_DESCRIPTOR DEVICE
        ACK 
0017002 ? [00010111] // 0279146 IN ADRS=00 ENDP=00
        NAK 
0017003 IN ADRS=00 ENDP=00 
        NAK 
0017004 IN ADRS=00 ENDP=00 
        NAK 
0017006 IN ADRS=00 ENDP=00 
        DATA1  12 01 00 02 00 00 00 08   
        ACK 
0017008 OUT ADRS=00 ENDP=00 
        DATA1  
        ACK 
0018114 SOF FNO=6EA
0018115 PRE 


PICWRITERをUSB接続すると最初にホストからはGET DEVICE DESCRIPTORリクエスト(デバイスディスクリプタ送信要求)が送られます。
80 06 00 01 00 00 40 00 です。
この意味は[第33回]で説明しました。
最初の 80 06 はGET DESCRIPTORです。
次の 00 01 はその要求がDEVICE DESCRIPTORを要求していることを示しています。
コード 01はDEVICE DESCRIPTORを示していて、00 はINDEXです(この場合には00になります)。
次の 00 00 はリクエストによって意味が異なりますがこの場合には 00 00 です。
最後の 40 00 はDESCRIPTORの長さ(バイト数)が最大64バイト(40H)であることを示しています。

説明が前後しますが、ホストから送出されるリクエストはアドレス00、エンドポイント00に対してSETUPパケットを送った後のDATA0パケットに続いて送出されます。
ホストはデータ(リクエスト)を送ると、そのすぐ後でINパケットを送出して、端末にデータを送るよう要求します。
端末はそれに対して準備ができていないときはNAKパケットを返します。
ホストは端末からデータが送出されるまで繰り返しINパケットを送ります。
ホストから送出されたGET DEVICE DESCRIPTORリクエストに対して、端末は要求に応えてDEVICE DESCRIPTORを送ります。
12 01 00 02 00 00 00 08 です。

ディスクリプタの最初の1バイトはそのディスクリプタの長さを指定します。
ここでは12ですから18バイトであることを示しています。
ディスクリプタの2バイト目は、そのディスクリプタの種類を示しています。
このディスクリプタがホストから要求されたDEVICE DESCRIPTOR(コード01)であることを示しています。
次の 00 02 はUSBバージョンを示します(USB2.00)。

[2014.4.2追記]
このほかのパートは大抵は1バイトまたは2バイトのバイナリデータなのですが、ここはBCD4桁のリトルエンディアン表記になっています。
リトルエンディアンというのは、下位桁を先に置く方式です。
8080、Z80、8086などインテル系のプロセッサはリトルエンディアン方式です。
Enumerationのコマンドやデータ中のバイナリデータもリトルエンディアンです。
わたしはかなり長い間リトルインディアンだと思っていました。
ワンリトル、ツーリトル、スリーリトルインディアン。小さいインディアンを先に置くジョークかと…(恥)。
もっともリトルエンディアン(little endian。この対語はビッグエンディアン big endian)という名前はやっぱりジョークでした。
「ガリバー旅行記」にある、ゆでたまごを小さい側から割るグループと大きい側から割るグループが対立するというお話(私は知りません)に由来するのだそうです。
[追記 ここまで]

次の 00 00 00 はクラスコードですが普通は00にします。
最後の 08 はエンドポイント0の最大パケットサイズの指定です。ここは8バイトを指定します。

このデバイスディスクリプタは18バイトなので、8バイト+8バイト+2バイトというように3回に分けて送ることになるのですが、ここでは最初の8バイトを送るとすぐにホストからデータの終了を示すOUTパケットが送出されて、デバイスディスクリプタの送信が打ち切られています。
USB接続をした直後はホストはデバイスが応答することだけをまず確認したいようで、このタイミングではこのようになります。

CPLD+SIMMを使ってUSBプロトコルの解析を![第36回]
2014.4.1upload
2014.4.2追記

前へ
次へ
ホームページトップへ戻る