2007-10

2007-09


もう10月

  • この暑さはなんなんだろう。
  • BBR-4MGを買った。
  • しかも新品でだ。正気の沙汰ではないなぁ。暑さのせいか?

さて、このルーターでWLAN APを作ろうと思うが、はたして気力が続くだろうか?

  • 中古のAPを買っといたほうが良かったかなぁ・・・とすでに後悔先に立たず。
  • だめだめだぜ。すでにAVRとは何の関係もない展開。

USB 3.0

MyCOMジャーナル連載記事

引用

>USB 3.0の信号にはPCI Express Gen2のx1 Laneの物理層(Electrical層とLink層)を
>そのまま流用した。ただし流用したのはここまでで、Transaction層は全く独自となる。 

>ソフトウェア面では、USB 2.0までのソフトウェアスタックをそのままUSB 3.0でも
>「なるべく」採用する。これにより、USB 2.0→USB 3.0への移行に要する手間をなるべく抑える。

ふーん。

ますますAVRとは無縁の方向だな。

LowSpeed , FullSpeed , HighSpeed と来て、次は何と呼ぶのかだけが興味の的だ。

いやいや、もしかしたらマイクロフレームの次にナノフレームが出来るかもしれないし、 超ハイスピードハブをAVRとPCの間に挟むことでPCから見たらAVR側が超ハイスピードデバイスに見えるのかもしれないという予測が当たったら笑えるというただそれだけだ。


BBR-4MGは、一瞬でLinuxBoxになった。

びんずめ堂 BBR-4MG::Linux化ファームウェア

  • びんずめ堂さんのLinux化ファームのおかげで、半田ごても改造も一切なしで(そうだ、蓋さえも開けることなく*1 )、 新品のBBR-4MGはものの3分もしないでLinux Boxになってしまった。

凄すぎる。

  • 2MのFlashによくこれだけ詰め込めますな。

BBR-4MGを改造してlinuxルータにする計画

  • こちらのほうは、USBを繋ぐために基板を改造して48MHzの水晶モジュールを接続して、USBメモリー にファイルシステムを置くタイプ。(ファームはU-BOOTだけを入れている)
  • BBR-4HGのほうは2000円くらい高いが、おそらく付属品(LANケーブル)とファームが違うだけなんじゃなかろうか。
  • FLASHはintelだった。
  • ADM5120Pはinfineon製のようだ。(ADMtechと違うの?)
    • (ADMtechはinfineonに買収されたらしい)
  • さすがに175MHzなので熱くなる。
  • 5.5V900mAの電源は重い。トランスのようだ。5W程度?買ってきた箱には定格3.55Wと書いてある。

AVRtermは19200に追いついてない。

  • 久しぶりにH8/3048FをUSBに繋ぐ。(19200)
  • VIAのUSBホストだと文字化けする。
  • SiSならOK。

えーと、VIAだとUHCIなので、7バイト受信トランザクションに4mS。

  • ってことは1秒に1750バイト。
  • ボーレートにすると14000ボー。
    バッターアウト!
  • VIAだめだめじゃん。
  • っていうかAVRterm使うためにHiSpeedハブかNECのUSBホスト買ってくる必要があるなんて・・・ナンセンスだよなー
  • 送信パケットのペイロードは4バイトより増やせないけれど、受信パケットを16とか32にしておいて、AVR側が可変長パケットで応答するというふうに変更しようかな・・・。面倒だけど。

AVRtermは19200に追いついた。

  • コントロール転送時の受信パケットを24バイトに増やした。
    ./checksize main.bin
    ROM: 1722 bytes (data=4)
    RAM: 109 bytes
    32バイトに増やすとたぶんスタックが足りない。
  • AVR_termも改造。
  • H8/3048Fのモニターと交信できた。
  • 文字落ちしなくなった。

ついでにW32_termのほうも同じプロトコルに改造した。

  • W32_termを使用してH8/3048Fとの交信に初成功

    おめでとう。俺 これでH8はめでたくWindowsの仮想COM:ポートに接続完了だ。
  • ちなみにUSBホストはインテル(UHCI)でハイスピードハブなし直結だ。

解説:

  • UHCIは1回のコントロール転送(ベンダリクエスト+8バイト受信)のトランザクションに4フレーム(=4mS)を費やす。
  • AVR_termではそのトランザクションで7バイトの受信データを転送するので都合14000ボーが転送スループットの最大である。
  • H8/3048Fのモニターは19200ボーに設定されている。
  • 間に合わない。


そこで、1トランザクションでの受信要求サイズを24に増やした。

  • 1回のコントロール転送ではベンダリクエスト(8バイト)+受信データ(可変長)最大24バイトを受け取るように改良した。
  • 24バイトの転送が発生すると2フレーム増加し6mSになるが転送量は23文字に増えるため、3800バイト/秒のスループットが稼げる。
  • これはビットレートに換算すると30400ボーだ。
  • これでも38400に達しないところが凧であるが・・・
  • こうしておけば、ハイスピードハブを挟むだけでこの3倍くらいはいけるようになる(はずだ)

(マイクロフレームのおかげ・・・)

  • AVR側のメモリー的にはRS232C受信バッファ(FIFO)が32バイトとUSB転送バッファ(PACKETバッファ)24バイトでだいぶ圧迫される。
  • これを1つにまとめられれば一挙にメモリー節約になるのだが・・・
  • たぶんigorさんのはまとめているのだろう。
  • なんとなく・・・チト無理か。

usbdrvasm16.S解読

このソースは芸術品だ。

  • クロック数のとおり寸分違わず時を刻むCPUのなんと有難いことよ。
  • 今どきのCPUはキャッシュがあるのでタイミングなんて合うわけない。


  • で、受信の同期取りはleapという8ビット変数だが。
  • 初期値=0
  • 1ビット読むたびに-3
  • 85回で-255(==1)
  • 1バイトは85.33333cycles
  • 最後に1引いて正(+)だったら3足して1サイクルNOP。
  • 「最後に」というのは1バイト受信後である。つまり1ビット単位でのleapはやってない。

さっぱり分からん。

  • 単純化するならば、85.3333という周期を生成したいなら、
  • {85,85,86}(のくりかえし)というふうにすればよい。
  • ほんとにバイト単位で3バイトに1回の1サイクル挿入をやっているのかどうか*2
  • 読解する力が足りない・・・


  • 送信は00101010(0x2A)というビットパターンをbitcntに入れる。
  • lsr bitcntするので、右から数えて、
    10, 11, 10, 11, 10, 11, というクロック進行になる。
  • あとの2ビットはどうするかって?そりゃアンロールされたほうのルーチンで制御だ。(didStuff6,didStuff7)
  • 送信についてはleapは使っていない。たぶん10.5cycle/bit固定なのだろう。
  • 誤差が10.6666 vs 10.50000(?) = 0.16666 / 10.6666 と1.5%くらいあるが、USBの許容範囲らしい。
  • むしろ10,11,10,11のジッターのほうが気になる・・・。

昔、磁気ドラムの回転(に同期するように)うまく利用して書かれた(大型?)計算機のプログラムがあったらしいが(ハッカーズディクショナリに書いてあった奴)、それに匹敵するくらいのトリックだ。


メルの物語

磁気ドラムの話は、うろおぼえだったので、Google先生に聞いてきた。
たぶんこれ。ちょっと極端かもしれない。


usbdrvasm16.Sを読み返すと・・・

  • やはり予想通り、受信時もEven bitとOdd bitで所要クロックを変えてある。
  • クロック進行は10,11,10,11,10,11だ。
  • これだと平均クロックが10.5000になり、16MHzで必要な10.66666cycle/bitと比べて 1.5%程度速いコード進行になる。
  • 8ビットで10.5×8=84クロックだ。
  • しかし、正確な8ビットの時間は85.33333cycleなので、1バイト受信ごとに1クロック遅れるようにしてさらに3バイトに1回で1クロック遅れさせると85.33333cycle/byteを達成できる。
  • 1.5%の誤差は1バイト単位でスタートビットの同期合わせが出来るRS232Cでは問題にならない*3が、
  • USBの最大パケット長はペイロードだけでも8バイトあるので(PLL的な処理でも入れない限りは)累積誤差*4でエラーを起こすことになる。

このソースは「メルの物語」に匹敵するほどの価値があると思う。


目次


*1 嘘。FlashROMのメーカーを調べるためと、CPUの発熱具合を知るために一回フタ開けた
*2 正確にはビットスタッフを含めた8ビット時間ごとに1回分の挿入と24ビット時間ごとに1回分の挿入が必要なはずだが、正味1バイトデータに対して1回の挿入になっているので誤差をどうやって処理しているのか解読出来なかった
*3 スタート、ストップビットまで合わせて10ビットあるから1.5×10=15%。パルス中央に対して最大15%ずれてもなんとか許容できる
*4 荒っぽく16バイト時間=128ビット時間を仮定すると1.5%×128=192%もずれて別のビットを読んでしまう