2014.3.2

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

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


[第23回]


●PICの内と外(2)

前回からの続きです。
前回の終わりに書きましたように、USB信号ラインから読み込んだデータとPICから出力されたデータをSIMMの同じアドレスに16ビットのデータとして書き込んだものを、読み出すときはパソコンのパラレルポート(プリンタポート)を経由する関係で、8ビットのデータとしてパソコンに取り込みます。
SIMMに記録するときは、16ビット×4Mのデータなのですが、それを読み出すときには8ビット×8Mのデータになります。
そのデータは8MBのバイナリファイルとしてWindows98のハードディスクにSAVEされます。
前にも説明しておりますように、Windows2000以後のOSではユーザープログラムが直接パラレルポートにアクセスすることを許してくれませんので、ここはどうしてもWindows98が必要なのです。

この8MBというファイルサイズにもご注目ください。
バイナリファイルを開くためのツールとしてMSDOSプロンプトでは一般にDEBUGコマンドが使われます。
私も最初はDEBUGコマンドで開こうとしてみたのですが、開けませんでした。
ファイルサイズが大きすぎるようです。
MSDOSの時代にはそのような巨大なファイルを扱うことは想定外だったのでありましょう。
そこでCPLD+SIMM回路によって得られる8MB〜32MBのバイナリファイルを読み込んで、それをメモリダンプ形式のテキストファイルに変換してSAVEするプログラムも作ってしまいました。
パラレルポートからデータを読み込んでバイナリファイルとしてSAVEするプログラムも、それをメモリダンプ形式でテキストイメージに変換してSAVEするプログラムもともに自作の8086アセンブラで作りました。
ええ。
マシン語のCOMプログラムです。
いずれそのプログラムについても説明をするつもりでおりますので、いつになるかはわかりませんが、どうか気を長くしてお待ちください。

さて、それで。
そのようにして記録しましたバイナリファイルは16進数コードのままですから、そのままではUSB命令を解読することは不可能ではありませんが、至極面倒です。
そこでバイナリファイルを読み込んでUSBコマンドに翻訳するプログラムも作りました([第17回]参照)。
これで役者がそろいました。

いよいよデータの解析です。
下はそのようにして準備をしたプログラムを使って解析を行なっているところを少しだけ取り上げて画像にキャッチして並べたものです。
各プログラムによって作成されるファイルはテキストファイルですが、ファイルサイズが大きいのでメモ帳などでは開くことができません。
フリーのテキストエディタTeraPadでやっと開くことができました。



画像の説明です。
一番上はUSBコマンド翻訳プログラムによって解読したEnumerationのごく一部を表示しています。
ホストから送出されたGET DESCRIPTOR(DEVICE)コマンドと、それを受けてPIC18F14K50から出力されたDEVICE DESCRIPTORデータのやり取りが記録されています。
各行の一番左の数値はこのファイルをTeraPadで開いたときの行番号です(紛らわしいのでこれは表示させないほうが良かったかも知れません)。
その次の7桁の数値は、元データのバイナリファイルを16進数ダンプ表示したテキストファイルをTeraPadで開いたときに表示される行番号を目安として表示しているもので、これは翻訳プログラムが計算してそのような表示をおこなっているものです。

その下が、メモリダンプ形式でSAVEしたテキストファイルの、翻訳データと同じあたりをTeraPadで表示させたところです。
行番号が位置の目安になっています。
ここでは幸いGET DESCRIPTOR(DEVICE)コマンドがそのまま読める形で16進数ダンプされています(ふつうはこんなに都合よくは読めません)。
35819行の赤で囲ったところがGET DESCRIPTOR(DEVICE)コマンドでその後ろの緑で囲った 80 D2 はPIC18F14K50から出力されたACKパケットです。
D2はACKパケットで、ここもそのまま読めています(パケットIDコードについては[第16回]を参照)。
その下の行の 0F 98 16 80 も4ビットずらせばそのまま読めます。
下位4ビット・上位4ビットの順に並べ直すと F0 89 61 08 で、08がSYNC、96がINパケットです。
次の 0F A8 B5 も同じように並べ直すと F0 8A 5B で、これはNAKです。
その次の35821行はそのままでは読めません。
ここは再びホストから出力されたINパケットを受けてPIC18F14K50からDEVICE DESCRIPTORデータを出力しているところです。
参考までに下にそのあたりのところを手作業で解読して示します。

35821 FF FF FF FF FF FF FF 03 A6 05 A0 EB 03 2E 49 04
35822 00 08 00 00 00 20 5C 9D EF 07 94 DE FF FF FF FF
35823 0F 18 5E 80 AE 03 2E 01 00 EC 03 4A EF FF FF FF

03       A6       05       A0       EB
11000000 01100101 10100000 00000101
          |        |       |   |
  SYNC     IN       ADRS=1  EP=0 CRC5

03       2E       49       04       00       08       00       00       00       20       5C      9D EF
11000000 01110100 10010010 00100000 00000000 00010000 00000000 00000000 00000000 01000000 00111010
          |        |        |        |        |        |        |        |        |        |
  SYNC     DATA1    12       01       00       02       00       00       80       00       CRC16

07       94       DE
11100000 00101001 01111011
           |        |
   SYNC     ACK

0F       18       5E       80       AE       
11110000 00011000 01111010 00000001 01110101 
            |        |       |   |        |
    SYNC     OUT      ADRS=5  EP=0 CRC5

03       2E       01 00 EC 03 4A EF
11000000 01110100 10000000 00000000 00110111 11000000 01010010 11110111
          |        |        |                 |        |        |
  SYNC     DATA1    00       CRC16             SYNC     ACK


そしていよいよさきほどの画像の一番下のところになります。
これはその上のUSBデータ4MBに続いて同じバイナリファイルの後半4MBとしてSAVEされた、PIC18F14K50から出力されたデバッグ用データを、その後半4MB分を分離して別のメモリダンプ形式のテキストファイルとして保存したものをTeraPadで開いているところです。
上の2つの画像とほぼ同じところを開いています。
やはり行番号が目安になります。
ただUSBデータの後ろにPICからのデバッグデータを連続してSAVEした段階でプログラムの都合でPICデバッグデータのほうが10バイトほど先頭がずれてしまいました。
ですので同じ行位置で見て、PICからのデバッグデータはUSBデータよりも+10バイトほど進んだ位置として表示されています。
しかし大体のところは、PICの外(USB信号)とそれに対する内側の動きとを対比させて見ることができます。

PICデバッグデータはこのままでは何のことだかわかりません。
これはPICプログラムのデバッグのためにプログラムの位置を示す値をPORTCから出力したものです。
下にPICプログラムの関係部分を抜き出して示します。

;
looptop
	clrwdt
	clrf PORTC;for test 2/7
	btfss UIR,0;reset?
	goto looptop1;not reset
	movlw 1
	movwf PORTC;for test 2/7
	lfsr 2,0f5c;UADDR
	clrf INDF2
	clrf UIR
	clrf bd2mk
	goto looptop
;
looptop1
	movlw 2
	movwf PORTC;for test 2/7
	clrf UIR
	movlw 08
	movwf UCON
;
	call setupck
	bz setup
	goto checkbd2; not "setup"
;
;"setup" received
;
setup
	call senddvck;"80"+"06"?
	bnz setadcheck
;
;(1)"GET DESCRIPTOR('80'+'06')" received
;
	movlw 3
	movwf PORTC;for test 2/7

looptopはUSB信号だけではなくて、Z80CPUからの呼び出しやRS232C送受信など多くの処理の要求をスキャンしたのち戻ってくるポイントで繰り返し処理の起点です。
デバッグデータとしてここでPORTCに00を出力します。
その後looptop1で02を出力して、SETUPコマンドの検出を行ないます。
SETUPが検出されると、SEND DESCRIPTOR(80 06)かどうかを判定します。
80 06 であるときはPORTCに03を出力します。
ここでさきほどの画像を見ていただきますと、35821行の終わり近くで03が出力されていることがわかります。
そのあとさらにコマンドを解析し、DEVICE DESCRIPTORの要求であることがわかると、そこでDEVICE DESCRIPTORの最初の8バイトを送出します。
その部分が下のリストです。

;
;send DEVICE DESCRIPTOR
;
senddev
	;movlw 12
	;cpfseq db6
	;call resetADDR
	movlw 0c
	movwf PORTC;test 2/7
	call setdevdsc0;send DEVICE DESCRIPTOR top 8bytes
	;call setbd0
	;call setbd1	
	goto looptop

デバッグデータとしてPORTCに0Cを出力します。
さきほどの画像で見ますと35821行の終わりで0Cが出力されています。

USBデータで見ますと 80 06 が出力し終わったのは35819行の終わりですから、上で説明した10バイトほどを補正しても、コマンドを受信してからそれに返信するまでにはまだ20バイト近くの遅れがあるように見えます。
ここでの20バイトは20×8/12≒13μsですからかなりの遅れです。
マシン語でプログラムを組んでも、コマンドを解読するにはどうしてもその程度の時間がかかってしまいます。
USBデータを見ますとホストからコマンドが送出され終わってから10バイトほどで最初のINパケットが出力されています。
それにはとても間に合いませんからPIC18F14K50からはNAKが出力されています。
その次の35821行の半ばで出力された2回目のINパケットでやっとDEVICE DESCRIPTORデータが出力されています。
なおACKやNAKはプログラムで出力するのではなくて、PIC18F14K50内蔵のSIE(Serial Interfaqce Engine)が自動で応答します。

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

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