SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|

2009-02-18(Wed) 簡易ながらラインモニタ成功

  しこしこと、秋月のWindows用PICプログラマのソースコードを読んでは、プロトコル解析をする今日この頃である。んが、こんなこと言ってはなんなんだが、このソースコードは驚愕の汚さだ。何度、同じコードを繰り返せば気が済むんだ……度を超している。これは、PICプログラマキットV4添付の物件であることから、初期バージョンに近い状態だと思うのだが、その時点ですら、九龍城砦も顔負けの増築っぷりである。

  いかにも「動いているところには絶対に触らない」という強固な意志の元、増築を繰り返したコードに見える。確かに「動いているところには絶対に触らない」というのは、この業界によくある掟かもしれないが、にしても限度があろう。まぁ、オイラのコードも、かなり一般には奇異なルールで書いているので、エラそうなことはいえないけれどもさ。

  にしても、問題は、結局、このコードは古いモノであって、最新のファームに対応したモノではないということだ。大いに参考にはなるものの、これに従って挙動すれば動く、ということは保障されない。やっぱり、ラインモニタで通信内容を盗聴しないとなぁ……。

  現在のラインモニタは、ライタからの通信は正常に得られるが、ライタへの通信がところどころ化け、内容がイマイチ安定しないという状態である。なんだか、電圧が逆に見えるのだが、不思議なことにPICの読み書きは正常にできてしまうのだよなぁ……

  画像の説明

  ……って、おいッ!! GNDとTXが逆じゃねーかッ!!

  そりゃ、ご丁寧に両端でHigh/Lowが逆なら、そういう挙動にもなるよな。アホか、オレは。

  気を取り直して結線を修正。ついでに、モニタ用LEDも実装した。信号がない時は、赤いLEDが点灯。通信が発生すると、白LEDがチカチカする。ふみふみ、正常にモニタできるようになったぞ。PICライタは半二重通信なので、RXとTXの両方を一度にモニタできるし、ジャンパを外せば、片方ずつモニタすることもできる。取得できる内容も完全に安定している。

  画像の説明

  しかし、問題は、RXとTXの両方を一度にモニタする都合上、送受信の内容が混じってしまい、それを区別できないこと。幸い、ワンショットのみの結果から解析する必要はないので、同じ通信を3回繰り返し、RXのみ、TXのみを別に採取して、合計3つのファイルから、送信と受信の内容を分離しようと、スクリプト「shotoku.rb」を開発しようと……したが、実はコレが結構に難しい。

  というのも、極端な話、相互に「0」ばかり話し合い続ければ、当然ながら分離は不可能。実際にはあり得ないが、ミクロな単位ではそれに近い状態がいくらでも起こりうるのだ。じゃどうするか。

  結局、通信内容をテキストに落としてdiffを取って分離することにした。実はdiffは上述の命題を限りなく解決するファジィなインテリジェンスを備えた、なかなかに高度なツールなんだよね。つまりは、送受信の混じった内容と、送信だけの内容、2回にわけてモニタして、前処理(seeable.rb)して、diffに食わせて、後処理(gather.rb)して、以下のような感じの結果が得ようって寸法である。

# 前処理のスクリプト
$ cat seeable.rb
#!/usr/bin/ruby
 
$stdin.each_byte {|c|
	printf("%02x [%s]\n", c, (c < 0x20 ? '^' + (c + 64).chr : (c < 0x7f ? c.chr : '')))
}
 
# 後処理のスクリプト
$ cat gather.rb 
#!/usr/bin/ruby
 
mode = ' Start'; d = ''; c = '<Start>'
$stdin.each {|l|
	if(l =~ /^(.) ([0-9a-f]{2} )\[(.*)\]/i)
		if(mode != $1)
			printf "%s %-48s [%s]\n", mode[0,1], d, c
			mode = $1; d = ''; c = ''
		end
		d += $2; c += $3.size == 1 ? $3 : '.'
		mode += 'LF' if(c.size > 15)
	end
}
 
# 送受信の混じった内容、今回は「PIC16F819への書き込み」をモニタし、前処理する
$ cat /dev/ttyUSB0 | ./seeable.rb > 819progRT
 
# 送信だけの内容をモニタし、前処理する
$ cat /dev/ttyUSB0 | ./seeable.rb > 819progT
 
# diffに食わせたものを、後処理する
$ diff -C 1000 819progRT 819progT | ./gather.rb
                                                   [<Start>]
  2a 2a 2a 3f                                      [***?]
- 41 45 2d 50 47 4d 38 37 37 20 20 56 36 2e 37 31  [AE-PGM877  V6.71]
- 0d 40                                            [.@]
  6d 44 0a                                         [mD.]
- 0a                                               [.]
  4e 72 73 63 00 08                                [Nrsc..]
- 3f ff 3f ff 3f ff 3f ff 3f ff 3f ff 04 e4 3f 10  [?.?.?.?.?.?...?.]
- 40                                               [@]
  40 2a 2a 2a 3f                                   [@***?]
- 41 45 2d 50 47 4d 38 37 37 20 20 56 36 2e 37 31  [AE-PGM877  V6.71]
- 0d 40                                            [.@]
  6d 44 0a                                         [mD.]
- 0a                                               [.]
  4e 62 64 0a                                      [Nbd.]
- 40                                               [@]
  4e 77 48 65 08 00                                [NwHe..]
- 00                                               [.]
  28 21                                            [(!]
- 01                                               [.]
  3f ff                                            [?.]
- 02                                               [.]
  3f ff                                            [?.]
- 03                                               [.]
  3f ff                                            [?.]
- 04                                               [.]
  :
  : ※以下、略。行頭が'-'が付いているのが、受信内容。何も付いてないのが、送信内容。

  つーわけで、簡易なラインモニタなら、わずかな部品を組み合わせるだけで作れるし、それで十分に実用的な範囲で送受信内容を推測可能なわけだ。どうしても、完全に送受信内容を分離したいなら、RXとTXを別々のシリアルポートでモニタする手も考えられる。なにも、2台のPCを用意する必要はなく、USBシリアル変換ケーブルが2本あればいい。この場合、全二重通信をモニタすることもできる。

  とりあえず、上記の内容を参考にしつつ、一応はPICへの書き込みに成功した。しばらくしたら、体裁を整えて公開する予定である。では。

  画像の説明

  それはそうと、やっと届いたよ。