HID Interrupt transferの動作確認

2008/09/08工作::USBimport

HID Report DescriptorとHostとの通信について(Interrupt Transfer)

デバイス設定:断りの無い限り,下記のとおりとする.

itemvalueremark
Poling cycle10 mSecInterface Descriptorで指定
EndPointBuffer size64 bytesInterrupt transfer

Report Descriptorで定義したサイズは固定長である.


転送サイズについて

Report Descriptorでは,Variable....という記載があったので,デバイス→ホスト間の転送サイズは任意であると考えていた.実際に動かして見ると調子が悪かったので,HIDは 原則固定長であると認識した.

実際にDevice/Host間で送受信データサイズを変えて確認した.ただし,いずれもデバイスのReport Descriptorでは 8bit 64count(64octet)とし,Interface Descriptorでは,EP sizeを64octetとしている.

Transfer directionfromtoRemark
IN transactionDEV: 64byte送信HOST: 64Bytes受信OK
OUT transactionHOST: 64byte送信DEV:64byte受信OK
IN transactionDEV: 1byte送信HOST: 64Bytes受信NG
IN transactionDEV: 1byte送信HOST: 1Bytes受信NG
IN transactionDEV: 64byte送信HOST: 1Bytes受信NG

Full Speed時は64byte(max)のユーザデータを送受信できるが,固定長となる.UARTの代替として使用する場合,もしくは64octetを超えるパケット通信の土管として使用する場合には,さらに一段ラッパーをかます必要がある.Low Speedもサポートするのであれば,パケットサイズが8octetになる.

 struct {
	Byte SizeOfData ;
	BYte Data[63] ;		// Low=63, High/Full=63
	}

PC側は,Report Descriptorを受け取って,capabilityとしてサイズを認識するので,データサイズは固定としない.デバイス側で,最大長となるように設定する.デバイスのメモリの都合・データ流量の都合により,削減する場合は,descriptor・interrupt transferの転送サイズをReport通りに修正するだけでよい.


取りこぼしについて(後方参照のこと!)

Interrupt転送は,デバイス-ホスト間でのデータ取りこぼしが起こりえないという話をどこかで見かけた.本当にそうなのかを検証してみた.*1

  • デバイスは複合デバイスとして実装した.同一USB portに複数のデバイスがぶら下がっているため,Interrupt転送を占有していない.← このため,最大負荷テストではない
  • PSoC側で1mSecの分周クロックを生成して*2,INパケットに積む
  • 毎パケット,+1したシーケンス番号を積んで,取りこぼしを検出する.
  • Host側は受信スレッドを作成し,受信開始からスレッドをまわす.取得したデータはQueueに積んでいく. 表示するときにQueueから吸い上げてListに突っ込む.
Poling Timing(Report)PO cycle実測結果Remark
10mSec8mSec取りこぼしなし周期が早いのは..?
1mSec2mSecかなりこぼす複合デバイスにしたので,最速では回らないか? スレッドで0秒寝かせているのが悪いのかもしれない.回りっぱなしでもトライする?.
2mSec2mSecかなりこぼします10/Sep.の追試実験用.条件よければOK.

※試験結果を随時追加していく.★疑問:GetInputReportBufferSize は なに?EPサイズでもreportサイズでもない.. reportの記憶回数でもない..



*1 : ホスト→デバイス方向は未確認

*2 : Sysclk=24MHz, VC1-VC2-VC3接続し,Timer8bitでカウント.VC1=15, VC2=16, VC3=100 → 1mSec

追記(10/Sep./2008)

同時期に,C++ Builderでホストプログラムを作成されている方より,取りこぼしはおきない旨,伺いました.Visual C#が癌なのかという疑いが出てきます.

ホスト側実装

前回の測定時のフローを示す.
1. 受信を Threadクラスを使ってぶん回す.ひたすらRead()を呼び出し続ける.
2. 受信したデータは,下記のクラスを用いてデータを積み上げる.

System.Collection.Generic.Queue<Byte>

このとき,スレッド内では,追加時にlock(Que)する.
3. Formスレッドで,上記クラスからenqueしてデータを取り出し,表示用のListControlに追加する.
このとき,lockなし,連続して吸い出している.

チェキ1

Formスレッドで,Queから読み出すたびに,Thread.sleep(0)を入れた.体感もっさりした気がする*3.取りこぼしは消えない.

追加情報

MSVSのmanualを見ると,動的に記憶領域を延ばすと書かれていた.追加時のオーバヘッドでもこぼしている可能性があるのだろう.
また,ロックの仕方に問題がありそう.本質的にスレッドセーフではないとあるので,記載どおりのlockを行う.
・・・ために,generic Queueではなく,Collection.Queueクラスを用いる.

チェキ2

ヘルプに記載のとおり,下記のlock()を適用する.

lock(myCollection.SyncRoot)

System.Collection.Generic.Queue<>ではなく,System.Collection.Queueを使ってみた.読み書き両方でlock()を使ったが,やはり駄目だ.
Byte[]の動的確保にも負荷がかかっているのだろう.開放処理もGCが走るだろうし.

チェキ3

表示させずにデータ取得させてから,表示してみる.
取りこぼしナシ.CPU負荷がそれなりにかかる模様*4

アプリケーション走行速度・データの扱い方による問題と思われる.

また,受信バッファは512byteまで指定可能のようだ.でかい値を放り込んでも拒絶される(32byte:report値に戻る?).
ただし,これによる救済措置が図れるのかは疑問である・・・.


結論

実は,チェキ1が終わった段階で,USB Snoopy Proを使用してPC側にデータが来ているかどうかを確認していた.
案の定,データが来ていることは見て取れたので,取りこぼしているのはドライバ~アプリのアタリであるとアタリがついていたのです.

そもそもHIDと言っている以上,ヒトの応答速度程度の情報を送受信するのが目的であるし,仕様なのかもしれない.
また,Report Descriptorを見ても判るように,固定長・ビット単位で意味を持たせたデータを送るのが目的であり,今回のようにストリームデータを送るのは想定外使用なのだろう.もし,確実に双方向のデータ通信を行いたいのであれば,ホスト~デバイス間でハンドシェイクを行う必要があるでしょう.

そこまでするならBulk転送で~とも思うのだけれど,それはそれでホスト側のドライバが面倒.汎用USBドライバやWinUSBといったものがあるようなので,それらの使用も視野に入れたい.
ひとまずHIDポート制御部分を切り出してコンポーネント化しておきたいところですね.

*3 : ListControlへの追加が遅くなっただけだろう

*4 : Core2Duo 2.4GHz(E6600)で30%超. VisualC# デバッグモードにて.Debug Writeも使用.

2008/09/03(水)[N:TM] その後とか

当日の動画

ニコ動で検索してください.手持ち素材で綺麗に出せるのは,たぶん,もう,ないはず.
当日,あわてて出発したので,テープを忘れたりして,撮影可能時間も短かったのですよ….

コンデジでも頑張ってみましたが,所詮デジカメ.動画機能は話になりませんね.音声だけでも録音したいと思っていたのだけれど,これまた持っていくのを忘れる始末.聴者としても準備不足でした(南無


動画を早めに作った理由はこれなんですよね,自分の興味を示したもので,かつ撮影状態の良いモノ.

Nico技wikiのほうに,当日発表された資料へのリンクがありますので,興味のある方はご参照ください.発表に動画を出されていたものはニコ動にうpして共有したいところではありますが.


触発事項

arms22氏のMPPTに興味をもって,ググってみた
すると製作事例が.
MPPT 充放電コントローラーの製作(TOP)
昔見た記憶があるナ...
秋月で買ったちっこいやつで,Zigbeeと組み合わせて電源供給フリーの気象観測端末にならないかなぁと思っていたんですよね.発電力があまりにもなさそうなので,まずはデータ取りからですかね.冬季の曇天でも動くようにできるのかしら・・・.



[不定期]本日のメモ*1

巡回跡メモ


本日のサボリ作業

ぇ-, あれだ.PC側のHIDデバイスとのinterrupt転送用ソフトいじくってます.C#で仕掛かり中.CPBでの実装要求アリ.

Borland C++ builderって,どうなの?世間様ではよく使われている??MFCよりは(なんとなく)軽快な気がするのだけれど.C#はCLIになってもっさりするから,GDI叩きまくったりポインタ操作したおしたりという細かい高速化が使いづらいと思うのね.とくにsafeコードを目指すときは.あえてunsafeを多用したけれど,結局何してるのかわからんようになったしw(むしろWin32nativeに近かったようだがな)

あぁ,そうだ.SH7144のI/Fシミュレーション.前に書いたけれども,図と結果が書いてなかったのね.精査ができてないけれども,おそらくシミュレーションOK.ただし,サイクルウェイト3・アイドルウェイト1を要する.
後者はRead時の出力が1クロックまるまる後ろにずれ込むために必須となった.R-W-R-Wの切り返しでバス衝突はしなさそうなのが救いかな...
サイクルウェイトが増えているのも,Readで1クロック増えている点が支配的.さらに同期化してハザードが乗ったときを考えると,Dataのsetup時間が微妙に不足する.t_accはmin.となっているが,その時間より短くデータを吐き出せはsetup不要という解釈をしたので,追加することとした.

結果,読み出し6サイクルかかることになった.50MHz時で,120nSecもかかってしまう.内部クロックをもう少しあげれば,サンプル速度があがって,setup時間が間に合うような気がするんだよなぁ.logic delayを見る限り,ギリギリ入るかどうかというところなのだけれど.
そろそろ実機配線してチェキりたいぜ...次はSH2か.

*1 : ココは私的な日記ネタは減らそうと思っていたんだけどなw

2008/09/02(火)[ROBO][HDL] SH7144 I/F回路検証

Verilog検証, SH I/F部

XSTのシミュレーションで holdtime timing violationが出る

検証用Test moduleをつくり,シミュレーションエラー*1が出ていたので,実装ミスかなと思い,放置していました.
放置しっぱなしでほかのことに手を出していたので少し復帰.試行錯誤してみたり,よくよく問題の文を読むと,どうやらtest moduleからの信号を受けて,hold timeが足りないといっているようです.非同期回路なのだから,不定値が乗ってもおかしくないですね・・・.

ということで,外部入力を全てDFF2段で受けた信号を用いることにしました.なんかおきてから直そうと思っていたら早速あたっていたわけですね.
ところが,コレを修正しても変わらない.不定値が伝播してシミュレーション結果が悲惨なことになっています.

検索しても結構ハズレばかりで,XSTのマニュアル(xst.pdf)や制約ガイド(cgd.pdf)もあわせて探しました.これらのマニュアル,非常に有用です.最初から見ておかないと駄目ですね.ボリュームが多くて手を出す気がおきないのも事実ですが.

さておき,制約ガイドのほうに,以下の属性が記載されていました.

ASYNC_REG

 ASYNC_REG は、タイミング制約で、
シミュレーションで非同期クロックをソースとしたデータの
ビヘイビアを向上します。特に、タイミング シミュレーション中に
X が適用されないようにします。
 タイミング違反があった場合、不定値は出力されず、
 それ以前の値が出力で保持されます。

使用例
 ▼Verilog-2001の属性として記述
  (* ASYNC_REG = "{TRUE|FALSE}" *) ; 

 ▼Constraints Fileにて記述
 INST instance_name ASYNC_REG = {TRUE|FALSE};

そのものずばり.該当する初段の DFF相当のreg宣言に対して属性をつけました.

  (* ASYNC_REG = "TRUE" *) reg [15:0] ADR_D ; 

Verilogの attribute宣言については,LRM 2.8のあたりを参照ください.

シミュレーションを実施したところ,不定値はなくなり,DFFがもう一段入ったような挙動になりました.1クロックだけ信号の変化が遅れるためです.実際の回路でも,前の値を保持する側に倒れた場合には,このような動作になるので,これでも動くような設計が必要となりますね...


制御信号全てdelay. WR strobe検出でさらに 1clock必要. → 信号類全てdelayさせて, 立ち上がり検出時にとりこむ.ホスト側が 立ち上がり~ほかの信号変化が1clock未満であることが条件.


IOBのDFFを使う

入力信号をそのまま記憶させれば,IOBのDFFを使うように合成されるようです.入力信号を組み合わせ回路に入れるような場合は,一度IOBから出てしまう模様.外部信号が同期を取って入ってくるようであれば,IOBで同タイミングで受けたほうが気持ちよいでしょう.
2段のDFFを通った後で加工しましょう.

*1 : setpup/hold timing violation

2008/08/30(土)[ニコ動] N:TM(技術部 高槻MT)

ニコニコ技術部関西勉強会

イベント詳細はニコニコ技術部 まとめwikiの,ニコニコ技術部関西勉強会を参照.

Make:東京が楽しかったという記事を見たこと,フェスタ68が濃いユーザが多かったことで,いってみた.ハードよりのイベントは希少なので,極力参加したいと思う.移動時間が3時間程度までなら...(コストはこの際無視だろjk)


本日の成果

  • 多くのニコ動 技術部の中の人と会えたこと.
  • 知らない分野へのポインタが増えたこと.
  • プロジェクトには可愛いおにゃのこの名前をつけること最重要事項

週末の睡眠不足と,空腹と疲労で記憶力が通常の半分以下に低下しておりました.それでもコレだけは覚えています,ということで('A`
あと,需要確認もかねて何なりと動画うpしていきましょう.ただし編集作業時間が結構かかるので,あくまでも補助的に.

自己のタスク消化が最優先.これは譲ってはいけない.だからこそコミケのサークル参加を封印したのだから...


記憶からサルベージ

単語だけ.気力と元気と記憶が残っていれば,動画エンコの合間に追記します.

  • Tr選別は300個くらいでも行うべし(FETだとコストかかりすぎるだろw
  • ロボットコンテスト参加支援者が居た!
  • マイコンカーラリーの電源は1系統.ノイズ対策も腕の見せ所
  • 初学者向けの動画需要もあるようだ
  • 高速回転ねぎ回しは5万以上じゃないと負ける(ナニ
  • 機構系設計・製作は大学・メーカの試作設備がある以上は,かなりきつい.
  • USBデバイスの頒布はVIDの問題が残る.・・・ニコ技にVIDを提供してくれる会社は出てこないか?w
  • FPGAは良いモノだ.マイコンも良いモノだ.(適材適所なんだよ・・・
  • ALTERAすげぇ.Avalon BUSすげぇ.Xilinx陣営はどうなんだろう...
  • オープンソース系のイベントも楽しいかもしれん.しかし,WEB屋畑の経験ないからなぁ...

関連リンク

ほか後日追加するかな... wikiのほうで補足されるか,動画のコメからリンク貼られるか・・・.こういう情報のまとめ方ってのも難しい罠.wikiコンテンツにリンク集を作って,記事ごとに小見出しをつけるか,孫くらいにまとめてもいいかなぁ.

[C#][USB] Host apllication on WindowsXP with C#

2008/08/30工作::USBimport

★本気時は書きかけのものです.頓挫する前に公開★

PC側のソフトを準備する

氏のsample"generichid_cs"から,必要なコードを流用する.C#では,Win32APIの呼び出しを直接行うことはできない.unsafe codeとして,DLLからAPIをimport宣言してやる必要がある.VBでWin32APIを用いるために宣言していたのと同様である.*1

*1 : .NET環境ではC#もVBも同じILに落ちると思いますけど

HostTest_01

  • device enumeration
  • detection of device attached/detattached
  • IN/OUT transaction check by using ReadFile/WriteFile

console applicationでもよさそうだが,今後のことを考えてGUIで作っていく.Formに配置するリソースを列挙する.

  • TextWindow or List Window
    • Status Window
    • Rx Data window(StatusWindowに書いておけばいいか?)
  • EditBox
    • Device ID
      • VID
      • PID
      • IF-ID
    • TxData
  • コマンドボタン
    • device detect
    • INPUT
    • OUTPUT

パクリ

下記のファイルをコピーする.ただし,VBのnamespaceも使ってるようなので,少し綺麗にしたいと思た.ちうことで,VBのlength/CRLFだけを使っていたので,これを排除しただけなんですがね.

  • Debugging.cs
  • DebuggingDeclarations.cs
  • DeviceManagement.cs
  • DeviceManagementDeclarations.cs
  • FileIODeclarations.cs
  • Hid.cs
  • HidDeclarations.cs


device enumeration

detection of device attached/detattached

IN/OUT transaction check by using ReadFile/WriteFile



HostTest_02

Include all functions of HostTest_01.


メモ

device change

WM_DEVICECHANGEメッセージが通知される模様.標準でフックできないようなので,WindowProcedureをoverrideしてsniffする.

class DeviceManagement(In file DeviceManagement.cs)

attached/removed検出
登録: RegisterForDeviceNotifications()
停止:StopReceivingDeviceNotifications()
DeviceManagement::Boolean DeviceNameMatch( Message m, String mydevicePathName )

WM_DEVICECHANGEメッセージを受けて,pathnameとマッチするかチェックする.マッチする場合はtrueを返す.

DeviceManagement::Boolean FindDeviceFromGuid( System.Guid myGuid, ref String[] devicePathName )

Uses SetupDi API functions to retrieve the device path name of an attached device that belongs to an interface class.


SetupDi APIを使って,interface classに属する接続されたdevice path nameを検索する.


参照資料

★MSDNより,C#で Num Text boxの作成 - 派生させてHex Edit boxでも作れ..~ 入力: hexのみ, 出力:':'区切りで表示, nibbleでfocus失うなら捨てる. 入力中は文字色変えるとか.

http://msdn.microsoft.com/ja-jp/library/ms229644(VS.80).aspx http://msdn.microsoft.com/en-us/library/ms790920.aspx http://msdn.microsoft.com/ja-jp/library/cc429201.aspx