今後の目標

今後の目標というよりネタ帳


HIDaspの再現はうまくいった。

  • では、次は何を作りたい?
    • とりあえずシリアルポートを作りたい。
    • 実現方法としては
      • CDCクラス(AVR-CDC)。ただし256バイト程度縮める必要がある。難しい。
  • igorさんのような独自ドライバー(は自分では作れないのでたぶんigorさんの再現テストだけで終わると思う)方式
  • AVR_Monitに埋め込む実装。---適当なコマンドでシリアルモードに突入する方式-普通のターミナルソフトが使えないのでAVR_Monitそのものを拡張して端末の代わりにする。--済
  • ComEmulDrv経由のシリアル接続がうまくいきそうなので、やってみたい。--済
    • これがうまくいけばH8write.cを動かしてH8/3048Fのファーム書き換えが出来るかも。
  • 旧型ADBバス接続のAppleキーボードをAT互換機(PS2バスかUSB)に繋ぎたい。
  • PC8801のジャンクキーボードをAT互換機に繋ぎたい。
  • なんでそんな欲求があるのかと言えば、実は101(104でも良い)英語キーが地方のPCショップではもう入手できなくなってるから。
  • 壊れたPCIカードから取り外した水晶を使ってAVR USBを動かしたい。
    • 豊富(?)にあるのが、25MHz(壊れた100BASEのNICから外したもの)
    • ATtiny2313では少しオーバークロックになる。
    • これで動かせるとめっぽう速い。(だから何なんだ?
    • 25だと三倍オーバートーン発振なんだろうなぁ・・・・発振するかなぁ・・・不安だ。
  • トラ技付録だったFPGA評価基板にAVRコアみたいなのを突っ込んで96MHz駆動させると LowSpeedでないSOFT USBが出来るかも(無理かも)
    • そんなことするよりも素直にUSBのIPを書き込んじゃったほうが良い?

PowerSwitch

  • AVRUSBのページにある、もっとも基本のアプリだ。
  • 8つのスイッチ(LED)をUSBから個別にOn/Off出来る。(専用のコマンドラインツールにて)
  • サイズは他と比べて小さいので、tiny2313に焼いても空きエリアが256バイトくらいある。
  • 一応動作確認までOK。
  • ただし、コントロール転送でSwの値を転送している。
  • 1000回送るのに3秒くらい掛かるような気がする。
  • 1回のパケットはLowSpeedでは最大8バイトなので8Kバイト送り込むのに3秒掛かっているわけだ。
  • 逆算で、2k弱/秒くらいしか転送出来ない???USBってそんなに遅いのか

HIDkeys

  • HIDkeys を試してみた。
  • これはUSBキーボードと等価な動作をするデバイスだ。
  • キーボード、マウス、GamePadといった人用対話型入力インターフェース(HID)クラスはマイクロソフトが定義したクラスなので専用デバイスドライバーがなくてもWindowsの標準デイバスドライバーが対応する。
  • つまり、デバイスドライバーの組み込みが不要なのだ。
  • atmegaだったので、tiny2313に書き換え。
  • タイマー0のプリスケーラーレジスタ名がすこし変わっていた。変更。
  • PortCは無いので削除。
  • USB接続ポートを変更。
  • 実際にスイッチは繋がなかったが、ちゃんと動いたようだ。
  • 改造crt.Sを使うと、
    ./checksize main.bin
    ROM: 1828 bytes (data=4)
    RAM: 61 bytes
    なので、サイズ的には200バイトくらい余裕。
  • INPUTエンドポイント1は使っているみたい。


  • これの応用で、CTRLとALTとDELだけが付いたSwとか。
  • USBメモリーに見せかけて、USBに繋がれた瞬間にリセットとかPowerOffを送り込む極悪USBkey。
  • 一定時間ごとに無駄キーとかマウスムーブを送ってPCをスクリーンセーバーモードにしないキー。(これって、何に使うんだっけ?)
  • 普通にUSBJoyPadは作れるよな。うん。

USB−SFR

  • CDCクラスで仮想COMポートをつくって、実際にはRS232にせずにAVR内部の対話シェル(?)でAVR制御が出来るといった感じ?(で良い?)
  • 当然tiny2313には入らないコードサイズ。
  • だが、SRAMサイズは足りている。

だいぶ改造に慣れたのでtiny2313に入れるテスト

  • 対話シェルのコマンドインタープリタをばっさり削る。
  • 当然crt.Sで圧縮。
  • これでも、コードは足りたがデータを含めると2048を越える。
  • しかたなく、watchDogを削る。
  • 肝心の対話シェルは使えないが、CDCクラスとしてWindowsに認識させることは出来た。
  • COM3という仮想ポートが出来ていて、teratermから接続できた。
  • USBスニファ SnoopyPro を使って、teratermとAVR間の交信が行われていることを確認した。
  • 単なる仮想COMポートのエコーバックサーバーならぎりぎり入る(?)かも
    • やってみた。うそくさいがエコーバック出来た。速度は秒間8kBで頭打ち。
  • 仮想COMまで作らずに、HIDaspのようにベンダーユニークのコントロール転送でコマンドを送り、AVRライターとしてではなく自分のIOポートの制御をさせることくらいならすぐにでも出来そうだ。
  • 欠点は制御が10mS単位になること。(なんで?)
  • 10mS毎にコマンドも含め8バイト送受することまでならHIDクラスで十分だ。

もうひとつ別のアイディア

  • tiny2313をペアにした基板を用意して、ATmega用のBootLoaderもどきをやる。
  • つまり、asp不要の(というか自己書き換えな)USBデバイスに近い。
  • 片方はHIDasp兼低速USB I/Fであり、もう片方はaspに常に繋がれて何時でも焼けるターゲットみたいな感じ。焼かないときは自律して動作してUSBでPCと交信可能だ。
  • ChaNさんのシリアルポートのISPなら、AVRが自律動作中はそのままシリアルコンソールになりうるので、(シリアルが使えるパソコンとISPがあるのならば、)わざわざ作るかという話もある。
  • ATmegaの手持ちがあるのなら、わざわざtiny2313を2個実装することもなかろう。 (無いけど

igorさん(スロバキアの人)のUSB to RS232というやつを拝見した。

  • tiny2313で57600bpsを実現している。これは約8KB/秒だ。
  • USBの1フレームは1mSであり、LowSpeedの最大パケットは8バイトなので、単純に考えると8kB/秒。
  • だが、ポーリング周期を10mSにしているとこの1/10になるので800バイト/秒(6400ボー???暴れるぞコラ!USBテメー1.5Mbpsなんじゃなかったのか!¥バキッ)
  • igorさんのは、Windowsカーネルドライバーで仮想シリアルを実現している。だから速い?libusbではだめなのか?(不明)
  • USB2.0 PDFを見ると、1フレームに8バイトのインタラプト転送は最大6個、有意バイト数で48バイトと書いてあるように見える(Table 5-6)のだが、目が悪いのか俺。
  • その後ろに、12Mbpsのフルスピードではインタラプト転送の周期は1〜255mSだが、LowSpeed の場合10〜255mSになると書かれている。詐欺だー。
  • で、igorさんはどうやって高速化したのだろう。Windowsのドライバーは難しくてさっぱり訳が分からん。

インタラプト転送のテストプログラム

  • 速度計測

独自USBシリアルとWindows側クライアントの作成。

  • CDCが容量的に無理くさいので、独自で試す。
  • Windows版シリアルドライバーは作成可能か?

バルク転送のテストプログラム

  • かなり無理そう・・・。
  • 実はUSB-Sfrのスケルトンを改造してCDCではないベンダユニークなデバイスを作って速度計測をしてみた。
    1回の送信バイト数コントロールWrite速度バルクWrite速度バイト数/フレーム
    8バイト8kバイト/秒8kバイト/秒
    16バイト16kバイト/秒16kバイト/秒16
    32バイト32kバイト/秒32kバイト/秒32
    64バイト32kバイト/秒32kバイト/秒32
    128バイト42.6kバイト/秒42.6kバイト/秒42
    256バイト42.6kバイト/秒42.6kバイト/秒42
    512バイト46.5kバイト/秒46.5kバイト/秒46
    1024バイト46.6kバイト/秒46.6kバイト/秒46
    なんだ。速いじゃん。LowSpeedでも
  • インタラプト転送はENDPOINT3がそれに相当するのだが、正しくハンドシェイクできていないようで、うまく動作してくれない。
    • CDCクラスでは、RS232のステータス転送に使っているような気がする。
  • LowSpeedの物理的な速度は1.5Mbps(約180kB/秒)だが、わずか8バイトのペイロードに対して、SYNC、ヘッダー、ビットスタッフ、CRC等オーバヘッドのほうがむしろ大きいのでまあ50kBも出るなら御の字なのかもしれない。
  • 8バイト以上のパケットを送って計測したが、まだ本当に正しく転送されているかは調べていない。データがこけてたら悲すい・・・。


エンドポイント・デスクリプタをbulkからinterruptに変えて、同様のテスト を行ってみた。

  • interrupt転送ではインターバルが10mS固定になっている。
  • CDCのENDPOINT3インターバルが2mSだったので、真似をしてみたが10mSより短くはならない。
  • それどころか、パケット長を増やすと応答時間が反比例して遅くなる。どうせ最大ペイロードは8バイトなので、ほんとに10mSに8バイトのパケットしか送らないようになっているようだ。
  • つまり、転送速度は1kB/秒に固定されている。(800バイトでないのが不思議だが・・・なんらかの帯域制限に掛かったような感じ)

これらの計測が正しいとしたら

  • LowSpeedで帯域を稼ぎたいならコントロール転送かバルク転送が有利。
  • インタラプト転送はクソ。
  • 但し、LowSpeedでのバルク転送はUSB1.1規格違反なので現在のWindowsXP以外で動く保障は無い。
    • Linuxではカーネルパッチが必要らしい。
  • コントロールWriteとバルクWriteはほぼ同じ速度が出る。
    • しかも1回の転送長を32バイトくらいにすればそこそこ速度は出る。
    • 問題はAVRのRAMが少ないこと、か。

AVR−CDC

  • tiny2313でUSBシリアルに挑戦。
  • ATMEGA8では可能(というか公開されている)
  • tinyでやるにはコードサイズを256バイト以上縮める必要がある。

そのまえに、基本的なインタラプト転送が出来るようにしたい。


バルク転送のテストプログラムその2

  • 同じベンチマークをインテル865/Pen4のマザーでやってみたら、遅いことに気づいた。
    1回の送信バイト数コントロールWrite速度バルクWrite速度バルクバイト数/フレーム
    8バイト2kバイト/秒4kバイト/秒
    16バイト3.2kバイト/秒8kバイト/秒
    32バイト4.5kバイト/秒15.8kバイト/秒16
    64バイト5.8kバイト/秒21.3kバイト/秒21
    128バイト6.7kバイト/秒25.2kバイト/秒25
    256バイト7.3kバイト/秒28kバイト/秒28
    512バイト7.6kバイト/秒29.8kバイト/秒30
    1024バイト7.8kバイト/秒30.8kバイト/秒31
    だめじゃんUHCI。
  • ちなみに前のテストで使ったマザーはSiS746F/Barton1.8GHz
  • どちらのテストも、マザボのバックパネルのUSBコネクタを使用。ハブなし。OSはWinXPで、OS環境はほぼ同じ。
  • これを見た感じでは、USBは遅くて使い物にならない。秒間2k〜4kBでどうせいと
  • なぜOHCIと比べて4倍以上も違うのか?特にコントロール転送遅いぞ!。
  • そもそもUSB2.0なんだからEHCIじゃなかったのかと小一時間。

いろいろマザーを変えて試すしかないのか俺。

  • がびーん、P4M890T(VIA)も遅かった。i865と大体同じ傾向。
  • もれなくインタラプト転送は常に1k/Sだが。
  • このままでは、ここは規格企画倒れやー。

VIA KM400Aで試してみた。

  • 上と大体同じだ。
  • 駄目押しで、i815(河童セレ)でも試してみた。まあインテルは皆一緒か。
  • 結論:速いのはSiSだけだった。

LowSpeed終了


もうLowSpeedには飽きた。

  • コントロール転送を1msに1回処理できないようなら見切りをつけるしかない。
  • SiS以外の大多数のUHCIでは4msに1回らしい。
  • 規格外のBulkで速度を稼ぐという手もあるが、それでも最大30kB/秒くらい。
  • Bulk受信がまだうまくいっていない。
  • Bulk送信のバリデーションもまだだ。




    と書いたが、まだやっている。
  • ターゲットをBulkに絞って、転送ルーチンを整理。
  • Win32側のベンチマークと連動させ、bulk-read とbulk-writeの速度計測。
  • おなじく、転送データのバリデーションもぼちぼち。
  • AVR側のサイズはコード=1684bytes SRAM=66byteまで縮めた。
  • 代償にinterrupt転送とcontrolのベンダーユニーク処理を全部カット。
    • 問題は・・・bulk-read / write は非同期なのでハンドシェークには使えないってことが発覚。
    • RS232CのTx/Rxと同じやね。

USB以外に目を向けよう。

  • 周波数カウンタ。(これは割りと簡単らしい)
  • RC計(デジタルテスターもどき)
  • 時計。温度計。
  • 赤外線リモコン。トランシーバー。
  • LEDゲーム。
  • 電子オルゴール。電子ピアノ。
  • USB-MIDIアダプタ。
  • MIDIオルゴール。
  • SDカードとの接続。
  • 液晶ドライバー。(H8のキットに付いてきた奴がまだ残っている)
  • データロガー。1秒間に100サンプル以下とかならUSBでも行けるか。
  • 簡易オシロ、簡易ロジアナ。これもUSBだと無理くさいが・・・。
  • USB-CDCは、結局tiny2313にやらせないほうがよいのか、それともigorさんのやつを試すべきか?

目次