USB応用
| 固定リンク | コメント (0) | トラックバック (0)
| 固定リンク | コメント (0) | トラックバック (0)
パフォーマンス・インジケーター その3
暑い!日中が暑い!!
仕事にならない位暑い。早く夏休み来ないかな~。
と、思っていたら残念な事実を知る。先週末、現在関わっている
プロジェクトのフィックスされた線表がメールで届いた。恐る恐る
開いて見ると。
げっ。夏休み無いじゃん!
9月までスケジュールが組んである。薄々解っていたが、目を逸らし
ていた現実を思い知る事になる。
まあ、こうなるだろうと思っていたし、現状のプロジェクトの進み具合
を考えるとしょうがないかぁ。10月になってから夏休みを貰うかと思う
が、10月は”夏”じゃないよな。
まっ、行楽シーズンだからいいか。
貰えるかどうか解らないが。
で、AVRでCPUゲージであるが、週末にコードを書いて一応完成した。
起動すると、通知領域にアイコンを表示しCPU使用率をLEDで
現す。
一応作りたかったものは出来た。が、もうちょっとこの
ネタで記事を書くつもりである。
| 固定リンク | コメント (0) | トラックバック (0)
パフォーマンス・インジケーター その2
驚いた事にまたヤフオクにBeBoxが出品されている!
幻のマシンだと思っていたのに、そんなにタマ数があるのかい?
当然、先週とは別の方が出品されているのだが、あるところにあ
るもんだ。ただ、スタート価格が6万円なんでやはり手が出ない。
2週連続で指を銜えるはめになるとは思わなかった。
BeBoxほしいな~。
さて、AVRでCPUゲージであるが、土日を利用してファームと
デバイスドライバを書いてみた。
AVRのプログラムとなるファームは、昨年作ったUSBCOMIOを
流用し、LED制御を組み込んで見た。肝となるのが、4つのI/O
ピンを使用して10個のLEDを制御する所だが、これはMicrochip社
にあるアプリケーションノートTB023を参考にしている。ダイナミック
点灯させて、見かけ上同時に複数のLEDが灯っているようにしてみた。
デバイスドライバは新規に書いて見た。USBCOMIOとは違い仮想
COMのフィルタが必要ないので、煩雑なI/Oコントロールが無い分
コンパクトに仕上がった。
にしても、カーネルモードプログラミングは驚きに満ちている。
単純なバグでタスクマネージャーからも終了できないプロセスを
作り出したり、時計が止まるほどのパーフェクトなハングアップを
作ったり、自由自在である。もちろんブルースクリーンも簡単に
引き出せる。
ほんとに単純なミスなんだけどなぁ。
解ってしまえばあっけないバグを修正しつつ、デバイスドライバ完成。
テストアプリケーションを書いて動作を確認。
ちゃんと動作している見たい。
次はWindows上の常駐アプリケーションだ。
今回、昨年書いたUSBCOMIOのコードを久しぶりに読んだが
なんかコードが汚い、よくこんなもんを公開してたもんだと
思わず赤面!公開した事に後悔する。(オヤジギャグ)
| 固定リンク | コメント (0) | トラックバック (0)
パフォーマンス・インジケーター その1
ヤフオクにて発見!
かつて憧れだったBeBoX!!
PPC603eをデュアルで搭載、正真正銘マルチメディアOS搭載。
ユーザーインターフェイスも筐体のデザインも、とってもイカす。
ずっとウォッチしてたんだが、最終的に価格は99,000円まで高騰。
流石に手が出ないなぁ~。
泣く泣く入札を見送る事に。中古コンピュータに10万円なんぞ払え
る訳が無い。何年か振りに、指をくわえて(オークションページの)
BeBoxを眺める事になった。
筐体の左右にLEDが並んでいて、チカチカと2つのCPUの稼働率を
表示している様がカッコいいんだよなぁ。と実物を見た事はないが、
BeBoxの代表的なギミックCPUゲージに思いを馳せる。
BeBoXは手に入らなかったが、このCPUゲージ電子工作の題材とし
ては、お手軽でいいかも知れない。WindowsマシンのCPUゲージを
AVRでもって作ってみようと思う。
Windowsマシンの場合CPU使用率はPDHと呼ばれるAPIで得られる
らしい。パフォーマンスモニタで表示されるヤツだ。PDHならCPU以外
にもディスクやメモリの使用量も得られる。
そこで、Windows上で動作する常駐アプリでCPU使用率を取得し、
AVRで作成したLED表示器を制御する。これらの装置間IFはUSBを
使う。作成するものは以下の通り。
LED表示器のファームウェアやWindowsのデバイスドライバは、
USBCOMIOを流用改造する。WindowsアプリケーションはMFCを
使ってお手軽に作ってみる事にする。それぞれの作業は大した
事はないが、AVRのファームはアセンブリ言語、デバイスドライバ
はC言語、WindowsアプリはC++言語という夢の言語コンボを味
わえる。
う~ん。
開発環境も、フレームワークもそれぞれバラバラ。
取り敢えずLED表示器のハードウェアから手を付ける事にする。
で、ちゃちゃっとレイアウトをでっち上げて、作ったのがこれ。
うぅっ!2箇所LEDの極性を間違えた。
幸いソフトで何となりそう。でも、美しくないなぁ。
| 固定リンク | コメント (4) | トラックバック (0)
USBCOMIO
最初は日々色々な事を書き綴ろうと始めたブログだが、このブログなんか電子工作ブログになってしまった感がある。結果、その筋のネタがないと書き込むべき記事が無くて、更新する気が起きなくなる。
いかん。
で、昨年からだらだらと続けている"AVRでUSB"であるが、最近
http://hp.vector.co.jp/authors/VA000177/html/FrontPage.html
でAVRUSBのEasyLoggerというのを知る。
これが凄い!何が凄いかと言うと、内蔵CR発振源のクロックで動作するUSBファームを書き上げている。実際ロースピードのUSBパケット1つを拾うのに必要な精度を以前計算した事があるが、とてもCR発振源では必要精度を満足させる事は出来ない気がする。
実際セラロックを使ってUSBファームを書いて見たが、特定のハードウェアではうまく動作しなかった。大半のマシンでは動作するのが、PCIバスに挿したUSB拡張カードでは不安定で認識にしくじる事がある。やっぱりクリスタルは必須かと思っていたが、そこに、
「内蔵CR発振源!?」
である。早速ソースコードを読んで見る。
「なるほど!やられた。」
物凄い衝撃を受けた。脳天に特大の金たらいが落下したくらいの衝撃!正直妬ましいくらいのアイディア。
簡単に説明すると、私のシステムの場合20MHzのセラロックを発信源に使っている。この場合、ロースピード1.5MHzのパケットを送受信するには、1ビットを13.333・・・クロックのタイミングでサンプリングする必要がある。
ただし、AVRで少数を含む数値をカウント出来ないので、3ビットサンプリングする毎に13,13,14クロックでサンプリングすれば、小数部の誤差をカバー出来る。
この方法で、20MHzの発信源を使ったAVRでも1.5MHzで作動するパケットを送受信できるが、1パケット送受信する間サンプリングするタイミングがきちんと拾うビットの遷移期間に収まっている精度が発信源に求められる。セラロックでは非常に微妙だ。
そこにCR発信源である。どう考えても必要精度を満たしていない気がするし、実際満たしていない。で、EasyLoggerでは何をやっているかと言うと、NRZIのビット挿入を省いた8ビット分(つまり1バイト)をサンプリングするために、必要なクロックより少ないクロックでサンプリングするループを組む。必然的にサンプリングタイミングは前方にずれる事になる。
そこで、各ビットをサンプリングする際、ビットの遷移期間の前方境界直後とビットの中央部をサンプリングして、この値が異なればサンプリングタイミングを後ろにずらすという方法で同期を取っている。
連続するビットが同じ値だと同期のずれを検出出来ないが、データはNRZIで符号化されていて、6ビット以上同じ値が続く事は無く、この方法は有効である。
「凄いわ。このコード」
このコードを読んで一気に発奮!同期補正を行うコードを組み込んで見る。
動作原理はこうだ。8ビット(1バイト)を1つのループで組み、各ビットを14,13,13,14,13,13,14クロックの周期でサンプリングする。これだと1バイトサンプリングする毎に0.333・・・クロック分サンプリングタイミングが後ろにずれる事になる。
そこで、1ビットサンプリングする際にビット中央部と後方境界を比較し同期を補正する。この方法で同期補正のついでに、0.333・・・のクロック誤差も補正する。
この方法でファームを書いてテスト。
「おおぉ。認識する!」
今まで接続が不安定だったPCとでも、安定して通信できる。
気を良くしたので、一気にWindows側のドライバも書き上げて見る。
出来上がったのがこれ。
AVR Tiny2313を使った汎用I/O。WindowsからはCOMポートとして見えるので、シリアル通信を行うアプリケーションからAVR Tiny2313のポートBを操作出来る。
senshuさんから紹介してもらったキットを参考にして、ブレッドボードに挿せるようにして見た。
ブレッドボード上で実験。うまく動作しているようだ。
取り掛かってから約1年掛かったが、何とかAVRでUSBデバイスを作る事が出来た。
一応「車輪の再発明」完結。
| 固定リンク | コメント (21) | トラックバック (0)
COMデバイス
ポチポチと Tiny2313 USB ファームの Windows ドライバを書いている。前回は(と言っても1月以上前になってしまったが)ほとんど「WindowsXPデバイスドライバプログラミング」のサンプル通りテストドライバを書いて見き動作を確認して見た。が、サンプル通りのコードを書いて見ても、今ひとつ WDM を自分の物にした気がしない。なので、1から自分で設計してみたい。
作る物は Tiny2313 のBポートを USB を通して PC から入出力出する汎用 I/O みたいな物を作って見ようと思う。アプリケーションから WriteFile で出力した内容を Tiny2313のBポートに出力し、Bポートの内容を ReadFile で読み出す事が出来るシステム。
たったこれだけの事なのだが、実装を考えると意外とめんどくさい。まず、Write/Read するにはデバイスのハンドルを得る必要があり、ハンドルを得るにはデバイス名を指定して CreateFile を実行する必要がある。USB の様に同一デバイスが同時に接続される場合、デバイス名の重複やそれぞれの識別を考慮する必要がある。一般的には GUID を用いて、Windows側でデバイス名を作成し、アプリケーション側はこの GUID を用いてデバイス名に辿り着くコードを書く。
が、自分で書いてて何がなにやらよく解んない。
UUSBD や USBLIB などの汎用 USB デバイスドライバは、専用ライブラリを用意して、アプリケーション側でこのライブラリをリンクする事で、めんどくさそうなデバイス名の取得の問題を解決している。流石です。
が、もう少し簡単にデバイス名を取得できる方法を泥臭く考えて見る。
仮想COMデバイスである。かなりレガシーだし、アプリケーション側からどの COM?? なのか判別する方法はないが、GUID からデバイス名を生成するよりは簡単な気がする。
ということで、デバイスオブジェクトに COM ポートへのシンボリックリンクを張る方法を調べる。INF ファイルにデバイスをポートクラスとして記述する。この INF ファイルでデバイスをインストールするとレジストリのハードウェアキーに COM 名が作成されるので、この名前をこのデバイスオブジェクトの物理デバイスオブジェクトにリンクする。あとは、レジストリの
\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOM
にデバイス名をキーとして、COM 名を登録すればいいらしい。
取り敢えず COM デバイスとして認識したようだ。
実際の Read/Write ルーチンはこれから書くよー。
| 固定リンク | コメント (0) | トラックバック (0)
CRC16
AVR Tiny2313でUSBデバイスは出来ている。そこで、こいつを使う
ための Windows用デバイスドライバを書かないといけないのだが、
何分素人なんで、デバイスドライバプログラミングなんてやった事が
ない。
解説書として「WindowsXPデバイスドライバプログラミング[入門と
実践]浜田憲一郎著」を用意した。私の様な素人さんにも解りやす
いらしい。
毎度の事ながら、解説書を読む。
毎度の事ながら、
うぅ~っ、わかんね。
なので、
毎度の事ながら、解説書を何回も読む。
という「毎度の事」を繰り返し、何とか
うっすら分かって来ましたよーっ!
で、うっすらUSBデバイスドライバを書いて見る。何とか認識されて、
Tiny2313のソフトで書かれたエンドポイントに対し送信。
うっすら受信出来ましたよーっ!
とりあえずUSBの通信は成功したが、さすがにTiny2313のメモリ
容量/スペックではUSBを実装するだけで、リソースをの殆どを
使い切っていてるし、所詮ロースピードデバイス。機能もうっすら。
これで何が作れるか、うっすら考えてみよう。
話は変わるが、USBのCRC計算法をググったあげく、当ブログに辿り
着いてしまった、というお気の毒な方がいらっしゃっる様なので、
私の付け焼刃の知識を恥ずかしながら披露する。
"HERO'S Download"から"AVRusb.ZIP"をダウンロード出来る。
この中にUSBの詳しいドキュメントがある。
USBのCRC16を計算するには「ハードウェアCRC16計算回路」
("USBspcs.pdf"に載っている)をエミュレートする。
Cで書くとこんな感じ
WORD UsbCrc16( int count, unsigned char *data )
{
int i, j;
WORD crc = 0xffff;
for( i = 0; i < count; i++ )
{
for( j = 0; j < 8; j++ )
{
if( crc & 0x0001 )
data[ i ] ^= 0x01;
crc >>= 1;
if( data[ i ] & 0x01 )
crc ^=0xA001;
data[ i ] >>= 1;
}
}
crc ^=0xffff;
return crc;
}
引数dataがデータの配列、countがデータ数で、戻り値が求めたCRC。
| 固定リンク | コメント (0) | トラックバック (0)
USBデバイスを作る6
久々の記事だがやってる事は変わらない。多少人生観は変わった
気もするが、行いが進歩する程の事でもなかったらしい。
なので、昨年の続きをやる。
Mega88でUSBロースピードデバイスのファームをでっち上げて、
Windowsから認識させる事が出来た。何とか。
そこで、自作デバイスドライバをスクラッチビルドしようと思うの
だが、その前に、実験用基板を作って見た。
Mega88は別の物を作るのに使ってしまったので、格安Tiny2313を
使用した。電源はUSBバスから三端子レギュレータで降圧した3.3V
を使う。クロック源は20MHzのセラロック。あとデバッグ出力用に
ADM3202ANを付けた。
さっそく、Mega88のコードをTiny2313用にコンバート。
げっ、フラッシュメモリの残りが数10ワード!
USBのファームだけで、ほぼプログラムメモリ満載。
こんなファームでなにか面白い物がつくれるのだろうか?
| 固定リンク | コメント (0) | トラックバック (0)
MorosanSoft再起動。
昨年末からほったらかしにしていた当ブログだが、
仕切り直すことにする。
人間生きていると色々な事が起こるものだが、
昨年末、長年勤めていた仕事を辞めた。
文具・事務用品の販売納品という仕事をしていたのだが、
販売形態の変化や地方都市の不景気という煽りを受け、
職場が廃業、職を失うという恐ろしくも情けない事態に陥った。
いや~、約20年振りに就職活動なんてもんをやってしまった。
今まで深く考えて無かったが、生きるということはコストが
掛かるという事で、生活するための金銭を稼がねばならない
という、当たり前の事実を痛感する事になる。何とか小さな
会社に潜り込む事には成功したが、
いい年こいて新入社員
という、違う意味で情けない事態に陥っている。
人生って色々あるな。
身辺も少し落ち着きつつあるので、当ブログも少しずつ
更新していこう。
| 固定リンク | コメント (0) | トラックバック (0)
USBデバイスを作る5
エニュメレーション成功。何とか、辛うじて。
AVRでUSBデバイスを作ろうとしてから2月、やっとPCから
USBデバイスとして認識させる事が出来た。
USBの場合電気的なインターフェイス/プロトコルを実装し
ても、その上層のUSBプロトコルを実装しない限りPCとの
通信は出来ない。
いやぁ、悩ませて貰いました。
ハマッた所
標準デバイスリクエストのSET_ADDRESを受け取っ
ても、すぐにアドレスを変更してはいけない。
↓
その後に続くシェイクハンド用入力指示PIDを受信
出来なくなる。
CRCの計算はハードウェア計算回路をエミュレート
する。
↓
良く見ると一般的なCRC計算とちょっと違う。
GET_DESCRIPTORの前に大量の入力指示PIDを受信
しても驚かない。
↓
それは、同じロースピードデバイスであるマウスや
キーボードの為のもの。ちゃんと自アドレスに向け
てのパケットか確認する。
バッファが空いているからといって、むやみにデータ
パケットを受信し、ACKを勝手に返してはいけない。
↓
データパケットはシェイクハンドにも用いられるので、
得られるはずのデータパケットを受け損なう可能性大。
ほかにも色々あったが、どれもきちんとUSBプロトコルを
理解していないのが一番の原因だった。
時間は掛かったがなんとか動いた。よかった。
やって見れば出来るもんだと、一人で勝手に感動。
しかしAVRって凄い。20MHzのセラロックと抵抗3本だけで、
USBデバイスが出来るかもしれない。しかも、リアルタイムに
データをNRZI変調して送信。受信側もNRZIから復号しながら
データを取り込む(挿入ビットの削除までは出来なかった)
事が出来だけのパワーを持っている。PICでは無理だ。
さて、USBデバイスとして認識させることは出来たが、これだ
けではPCと任意の通信はできない。PC上のドライバが必要
だ。なので、次はデバイスドライバーを書いてみようと思う。
が、デバイスドライバーを書いた経験は無い。いつもの事だ
が出来るかどうか分からないが、取り敢えずやってみよう。
| 固定リンク | コメント (2) | トラックバック (0)
最近のコメント