2014.3.12

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

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


[第27回]


●STRING DESCRIPTOR(2)

前々回([第25回])からの続きです。
STRING DEASCRIPTORの送受信の記録を見ていただいて、そこにおかしなところがあるのですがそれがどこだかわかりますでしょうか、というところで終わりました。
もう一度そのリストをお見せします。

(D6PX6CK.TXT)
0025900 SOF FNO=73D
0025910 SETUP ADRS=04 ENDP=00 
        DATA0  80 06 03 03 09 04 FF 00   GET_DESCRIPTOR 
        ACK 
0025912 IN ADRS=04 ENDP=00 
        NAK 
0025913 IN ADRS=04 ENDP=00 
        NAK 
0025914 IN ADRS=04 ENDP=00 
        NAK 
0025916 IN ADRS=04 ENDP=00 
        DATA1  10 03 4F 00 6C 00 48 00   
        ACK 
0025918 IN ADRS=04 ENDP=00 
        NAK 
0025918 IN ADRS=04 ENDP=00 
        NAK 
0025919 IN ADRS=04 ENDP=00 
        NAK 
0025920 IN ADRS=04 ENDP=00 
        NAK 
0025922 IN ADRS=04 ENDP=00 
        DATA0  6F 00 73 00 73 00 00 00   
        ACK 
0025922 IN ADRS=04 ENDP=00 
        NAK 
0025924 IN ADRS=04 ENDP=00 
        DATA1  
        ACK 
0025926 OUT ADRS=04 ENDP=00 
        DATA1  
        ACK 
0025960 SETUP ADRS=04 ENDP=00 
        DATA0  80 06 00 02 00 00 FF 00   GET_DESCRIPTOR CONFIG
        ACK 

このリストでは、ホストから送出されたGET DESCRIPTORコマンドと、それに応えてPICWRITERからSTRING DESCRIPTORが送出されたところが記録されています。
ホストからの送信要求に応えてPICWRITERが送信した最初の8バイトのデータは
10 03 4F 00 6C 00 48 00 
でした。
先頭の1バイトはこのディスクリプタの長さを示しています。
10Hですからこのディスクリプタ(シリアルナンバー)は全体で16バイトであることを示しています。

ホストからは何回もINパケットが送られていますが、準備ができていないときはNAKを返しています。
まともに応答したのは2回ですから、8バイト×2=16バイトのデータを送っています。
PICWRITERはこれで必要なデータ16バイトを送りましたし、その長さが16バイトであることはデータの先頭に10Hを置いたことでホストも当然わかっているはずです。

ところが16バイトを送り終わったにもかかわらず、ホストからはさらにINパケットが送出されています。
おかしいと書いたのはそこのところなのです。
25922行で最後の8バイトを送出したにもかかわらず、その直後にまたINパケットが出されています。
このときはPICWRITERはまだ応答の準備ができていないらしくNAKを返しています。
次の25924行のINパケットではもう何も送るデータがありませんから、データなし(0バイト)のDATA1だけを返しています。
そこでやっとホストからは全てのデータを受け取ったしるしとしてデータなしのDATA1が送出されて、これでやっとSTRING DESCRIPTORの1つのやり取りが終了しました。

しかし、ここで記録されたやり取りは、上で説明しましたようにどう考えても納得がいきません。
このやり取りからはSTRING DESCRIPTORの先頭に置いたデータ長の1バイトが全く無視されてしまっています。
こんなことになっているとは全く考えてもいませんでしたから、私のPICプログラムでSTRING DESCRIPTORを送るようにしたときには、最初はほかのDESCRIPTORと同様に必要なバイト数だけを送ってそれでおしまい、という風に書いたところ、それが原因で「不明なデバイス」にされてしまいました。
そこで、おかしいと思って繰り返し記録をとって調べたところ、上記のことが明らかになったのでした。

このことが明らかになった当初は、これがUSB3.0固有の振る舞いであると思いました。
しかし念のためにほかのWindowsパソコン(USB2.0)で調べてみたところ、USB2.0でも全く同じであることがわかりました。

下はWindows98SE(USB2.0)にPICWRITERを接続したときの記録データを解析したもので、上のリストと同じ部分のリストです。

(D6P9_2CK.TXT)
0325092 SOF FNO=26A
0325093 SETUP ADRS=02 ENDP=00 
        DATA0  80 06 03 03 09 04 FF 00   GET_DESCRIPTOR 
        ACK 
0325187 SOF FNO=26B
        IN ADRS=02 ENDP=00 
        DATA1  10 03 4F 00 6C 00 48 00   
        ACK 
0325279 SOF FNO=26C
0325281 IN ADRS=02 ENDP=00 
        DATA0  6F 00 73 00 73 00 00 00   
        ACK 
0325373 SOF FNO=26D
0325374 IN ADRS=02 ENDP=00 
        DATA1  
        ACK 
0325467 SOF FNO=26E
0325561 SOF FNO=26F
0325562 OUT ADRS=02 ENDP=00 
        DATA1  
0325655 SOF FNO=270
0325748 SOF FNO=271
0325750 SETUP ADRS=02 ENDP=00 
        DATA0  80 06 00 02 00 00 FF 00   GET_DESCRIPTOR CONFIG
        ACK 

見ていただければわかりますように、さきほどのリストと全く同じです。
これはSTRING DESCRIPTORだけに見られることのようで、他のDESCRIPTORの送受ではこのようなおかしなことはおきていないようです。
そしてそれはUSB3.0だけではなくてUSB2.0でも同じであることから、何らかの理由でSTRING DESCRIPTORについてはこういうルールになっているものと思われます。

ところでこのリストではコマンドやデータの送信や受信がSOFで始まる1つのフレームに1回というように、ゆっくりとしたやり取りで行なわれていることがおわかりいただけると思います。
さきほどのリスト(USB3.0)ではINパケットが10〜20μs毎という非常に短い時間で出されているのですが、このリスト(USB2.0)ではフレーム毎(1フレームは1ms)というゆっくりとした間隔で出されています。

[第21回]に書きましたように、私はそういうものだと理解してPICプログラムを書きましたので、USB3.0の猛烈な速度には応答できなくて結果として「不明なデバイス」にされてしまったのでした。
勿論今はUSB3.0の速度にも応えられるようにPICプログラムを修正しましたので、それでやっと「不明なデバイス」問題はクリアできました。

CPLD+SIMMを使ってUSBプロトコルの解析を![第27回]
2014.3.12upload

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