• ベストアンサー

USB機器からのデータ受信による割り込み処理について

お世話になります、fujitomoです。 まだ実際にプログラムのコードを開発しているわけではないので、漠然としたイメージでの質問となるのですが、質問させて頂く内容は USB機器で取得した測定データを、USB機器からアプリケーション(C++ MFCにて開発)に送信し、受信時に割り込み受信の処理をし、そのUSB機器から送信されたデータをリストやダイアログ上に表示させたいと思ってるのですが、その実際の実装方法の流れを教えていただければと思い、質問いたしました。 シリアル通信と同様にUSB用の割り込み受信関数といったようなものがあるのでしょうか? 全体の流れのイメージが掴めず、どこから着手していいか分からないため、ご存知の方がいらっしゃいましたら、ご回答宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

Windowsと仮定しますが、Windowsではアプリケーションが直接USB機器にアクセスする事は出来ません。 USB(と言うか、正確には「Windowsのカーネルシステムが認識しているUSBポート」ですが)は、Windowsのカーネルシステムが占有しています。 特定のアプリが特定のUSB機器を制御するには「その機器専用のデバイスドライバ」を介して行う事になります。 「Windowsのカーネルシステムが認識しているUSBポート」に「USB機器」が接続されると、Windowsのカーネルシステムは「お前は誰だ?」と、機器に問い合わせを行います(Inquiryコマンドの発行と機器問い合わせ) そして、問い合わせた結果「お前を制御するデバイスドライバがインストールされてない」と判ると、デバイスドライバのインストールを要求して来ます。 なお、デバイスドライバがインストール済みであれば、認識後の初期化処理をデバイスドライバに行わせ、それ以降の機器アクセスはデバイスドライバに一任します。 で、無事にデバイスドライバがインストールされ、機器の初期化と認識が終わると、デバイスドライバは、アプリケーションで使用可能な「アプリ用のソフトウェア的なインターフェース」を提供します。 つまり「アプリがデバイスドライバを利用可能になる」わけです。 「アプリ用のソフトウェア的なインターフェース」が「その機器専用の物」なのであれば「デバイスドライバを作った人が勝手に決めて良い」ので、アプリからして見れば「デバイスドライバの仕様書の通りに、決められた通りにインターフェースを行う」しかありません。 「アプリ用のソフトウェア的なインターフェース」が「USBメモリのような、標準的な外部記憶装置としてのインターフェース」であれば、アプリケーションは「普通のファイルにアクセスするように、そのドライブ装置にアクセスするしかない」ので、悩む余地はありません。 そういう訳で、アプリを書くのは、そんなに大変ではありません。 問題なのは「その機器専用のデバイスドライバ」です。 BIOSを介して、または、Windowsのカーネルルーチンの呼び出しを駆使して、機器をコントロールしなければなりません。送信タイムアウトとか、受信タイムアウトとか、データのバッファリングとか、コマンドの強制中断とか、ユーザーによる機器の取り外し要求に対するデバドラの終了処理とか、機器に対するリセット指示とか、機器が応答しない処理とか、あらゆる場合についての機器の制御が要求されます。 それと同時に、アプリ側とのインターフェースも行わないとなりません。機器の機能を過不足なくユーザーに提供する為の、考えられる限りのインターフェースをアプリに提供しなければなりません。「この機器の、この機能は、パソコンと接続した場合は、デバイスドライバで未サポートなので使えません」じゃ困りますからね。 また「その機器が繋がっているUSBポートには、USBハブを介して、別のUSB機器が繋がっている」ので、例え割り込みで「受信したぞ~」って言われても、勝手にUSBポートにアクセスしに行ってはいけません。その割り込みは「他の機器が発した、他のデバイスドライバに対する割り込みで、自分宛じゃない」のかも知れませんから。 そんな訳で「もし、デバイスドライバの開発をする部署なのであれば、即死できる」と思います。デバドラの開発は「簡単に死ねるほど複雑」ですから。 とは言え「コード書いた人間に、デバドラのコードを書かせたりはしない筈」なので、ま「1年半は勉強のつもりで下積み」をやらされるでしょう。 大変でしょうが、がんばってくださいね。

その他の回答 (5)

  • usatan2
  • ベストアンサー率37% (163/436)
回答No.6

>USB用の割り込み受信関数といったようなものがあるのでしょうか? USB機器にはデータ受信による割り込みはありませんよ。 「見かけ上でも」という問いに対しては、デバイスドライバ次第、としか答えられません。 割り込み転送というモードがありますが、本当の所はポーリングです。 つまりUSB機器は、「CPUからの問い合わせに対し、応答する」しか通信の方法がありません。 見かけ上、「データ受信による割り込み」を実現するには、 「その機器専用のデバイスドライバ」をつくり、デバイスドライバがたとえば16/1000秒毎にUSB機器に対し、「受信データありますか?」と問い合わせをし、「ある」と答えたとき、アプリケーションに対し割り込みをかける ことで実現しています。 USBポートには複数のUSB機器がハブなどを通して接続されている可能性があるので、特定のUSB機器への問い合わせは、勝手にできません。デバイスドライバは、1ms(USB2では1/4ms)周期で繰り返し転送されている「フレーム」の予約席を確保し、確保したタイミングにすばやく、問い合わせをする必要があります。No3さんの回答のように、このデバイスドライバの作成は、「簡単に死ねるほど複雑」です。

回答No.5

まず、USBにはいくつか転送モードがあります。 割り込み転送:HIDデバイスのような不定期通信。 バルク転送:データ保証あり。USBストレージに使用。 インタラプト転送:帯域保証のため、データエラーでも再送信はしない、USBカメラなど。 (コントロール転送は、この質疑では除外) このどれもが、「USB機器から割り込み通信があった」ということをアプリケーションレベルでは通常取得することはできません。 たとえば、USBマウスを接続したとしても、OSからは「USBデバイス」として認識されますが、OS介してアプリから見ると「(USB接続された)マウス」でしかなく、扱いは「マウス」にしかならないからです。 つまり「USBデバイス」(それ以外の接続機器も)直接I/Fが何かということを知る術がないのです(COMポートは「COMポート」というH/WとしてOSがアプリに通知しているので別)。 そのため、割り込みタイミングを直接取得するためには一般的には専用のデバイスドライバ(とDLL[API])を作成し使用(提供)します。 尚、 >シリアル通信と同様にUSB用の割り込み受信関数といったようなものがあるのでしょうか? 「USBデバイス」というくくりからでは「ありません」というのが回答です。 USB-COM変換の場合はエミュレーションを行っているドライバー次第です。(アプリからは「COM」として見えているから) その他のデバイスもやはり「ドライバー次第」という回答になります。

回答No.4

訂正 誤:とは言え「コード書いた人間に 正:とは言え「コード書いた事のない人間に 申し訳ありませんでした。

  • wathavy
  • ベストアンサー率22% (505/2263)
回答No.2

あ、こっちでした。 http://www.picfun.com/usbframe.html すみません

  • wathavy
  • ベストアンサー率22% (505/2263)
回答No.1

USBのプロトコルについては、 http://www.picfun.com/usb20frame.html 辺りをご覧になられてはいかがでしょうか?

関連するQ&A