PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.7.10

前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆C++でUSB(HID)アクセスプログラムを作成

PIC側のプログラムはC18コンパイラを使わずPICアセンブラで作成しますが、パソコン側のUSB(HID)アクセスプログラムはBorland C++コンパイラで作成します。
しかしこれがまた難物で悪戦苦闘の連続でありました。

[第47回]

●まだ不足しているファイルがありました

前回([第46回])で、USBコネクタにHIDデバイスを接続して、HIDテストプログラムを実行したところ、Windows98では正常な結果が得られたのですけれど、WindowsXPではUSBマウスの正しいVenderIDとProductIDが得られませんでした、ということを書きました。

これは何とか解決しなければなりませんから、思いつくままにソースプログラムを書き換えてカットアンドトライをしてみることにしました。

前回も書きましたが、私は普段はWindowsXPは使っていません。
もっぱらWindows98を使っております。
当然、今回のHIDテストプログラムもWindows98マシンの上で作成〜コンパイルして作りました。
ところが、今回の不具合発生です。

ことはWindows98でのトラブルではなくて、WindowsXPで発生したトラブルです。
それを何とかするために、ソースプログラムを書き直して、コンパイル、そして実行という作業を繰り返すのに、いちいちWindows98マシンに持っていって、そこでコンパイルしてから、またEXEファイルをWindowsXPマシンに送って、そこでテストをしてみる、なんて面倒なことはやっておれません。

で、WindowsXPマシンの上で、書き直したHIDテストプログラムをコンパイルしてみました。
WindowsXPマシンにもBorlandC++コンパイラはロードしてあります。
ですけれど、このHIDテストプログラムをコンパイルするのははじめてです。

[第42回]で過去の作業を思い出しながら書きましたように、ロードしたままのBorlandC++コンパイラには、HIDプログラムのコンパイルに必要ないくつかのファイルがインクルードされておりません。
それについては先刻承知ですから、Windows98マシンでの作業フォルダごとWindowsXPマシンにコピーして、そこでコンパイルをいたしました。

そうしましたら、下のようなエラーが表示されてしまいました。


hidpi.hをもってくるのを忘れておりました。
Windows98マシンでは、どうやらBorlandC++のライブラリフォルダに入れてしまっていたようです。
このhidpi.hについては、hidsdi.h、hid.libとともにWin98DDKからもってこなければならない、ということを、[第42回]で書きました。

でも画面をみますと、hidpi.hのほかにもうひとつ、hidusage.hというファイルが必要だ、というメッセージが出ています。
hidusage.hについては完全に忘れておりました。
このファイルもWin98DDKに入っております。
これもBorlandC++のライブラリに入れてしまっていたようです。

ここであらためて、[第42回]で書きましたことの訂正です。

BorlandC++でHIDプログラムをコンパイルするためには、Hid.lib、Hidsdi.h、Hidpi.h、Hidusage.hが必要です。
これらのファイルを私はWin98DDKから、BorlandC++の作業フォルダにコピーしました。

●WindowsXPではUSBマウスが「邪魔」になります

前回([第46回])の最後に書いたことです。
あ。今回の冒頭でも書いておりました。

このままでは、WindowsXPでUSBマウスを接続していると、「VenderIDとProductIDがダブッて検出されてしまいます」から、VenderIDとProductIDからターゲットのデバイスを特定することができません。
なので、これは、なんとかしなければなりません。

HIDデバイスのVenderIDとProductIDの検出は、HidD_GetAttributes関数で行っています。
HIDテストプログラムの、その部分です。

        HANDLE handle = CreateFile( dev_det->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
//
        HIDD_ATTRIBUTES attr;
        HidD_GetAttributes( handle, &attr ) ;
        cout<<"VenderID: " <<attr.VendorID <<endl;
        cout<<"ProductID: " <<attr.ProductID <<endl;
	cout<<endl;

なぜ、WindowsXPでは、USBマウスのVenderIDとProductIDが正しく表示されなかったのか、ということについてですが、どうもCreateFile関数で取得したhandleが怪しいのではないか、と推測しました。

そう思ったら、それを出力して、確かめてみるのが一番です。

HIDテストプログラムを少し直して、handleの値も出力させてみるようにしてみました。
ここではUSBマウスと秋月のPICプログラマだけをUSBコネクタに接続しています。

秋月のPICプログラマのhandleは7ACで、これはごくふつうの値ですが、一方USBマウスの方は、FFFFFFFFです。

う?
FFFFFFFF?

おおお。
そうか。
ひょっとしたら。

FFFFFFFF=−1、ではありませんか。

もしも、そうだとしたら。

CreateFile関数について調べてみました。
CreateFile関数は、MSDNライブラリ(http://msdn.microsoft.com/ja-jp/library/cc429198.aspx)にあります。

そのページから一部を引用いたします。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
戻り値

関数が成功すると、指定したファイルに対する、開いているハンドルが返ります。
(途中省略)
関数が失敗すると、INVALID_HANDLE_VALUE が返ります。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

おお。なるほど。
すると、さきほどのFFFFFFFFというのはINVALID_HANDLE_VALUEなのかも。

そこで、次の文を追加して、試してみました。

if(handle==INVALID_HANDLE_VALUE)cout<<"INVALID_HADLE"<<endl;


おお。
ビンゴ!です。

●USBマウス対策です

それなら、こうしてみましょう。

        for( int index = 0; ; index++ )
  {
        cout<<"search"<<endl;

      (この間省略)

        if(handle==INVALID_HANDLE_VALUE){cout<<"INVALID_HADLE"<<endl;continue;}

        HIDD_ATTRIBUTES attr;
        HidD_GetAttributes( handle, &attr ) ;
        cout<<"VenderID: " <<attr.VendorID <<endl;
        cout<<"ProductID: " <<attr.ProductID<<endl;
        cout<<endl;
//
        CloseHandle(handle);
   }

で、もう一度実行してみました。

これで、USBマウスのために、ゴーストのように出ていたニセのVenderIDとProductIDは表示されなくなりました。

handle=INVALID_HANDLE_VALUEのときにはHidD_GetAttributes関数を実行しないように、continue文でFORループの後半をパスさせましたが、そのことでfor文が途中で打ち切られたりしていないことを確かめるために、for文の直後に、
cout<<"search"<<endl;
を追加してあります。

このように対策することで、USBマウスを接続していても、VenderID、ProductIDが誤表示されることが避けられましたから、VenderID、ProductIDからターゲットデバイスを特定することが妨げられることはなくなったと思います。

ところで、Windows98ではできていたのに、なぜWindowsXPでは、CreateFile関数でUSBマウスが検出できずにINVALID_HANDLE_VALUEが返されてしまうのか、ということについてですが…。

さて、それはなぜでしょうかねえ。
私には、わかりませぬ。
マイクロソフト様に聞いてみてくださいませ。

ああ。多分USBキーボードについても同じことになると思います。
今、私の手元にはUSBキーボードがありませんから、それについてはなんともわかりかねますが、近いうちに入手して試してみることにいたします。
CPUをつくろう!第474回(2010.4.10upload)を再編集

PICでUSBを![第47回]
2011.7.10upload

前へ
次へ
目次へ戻る
ホームページトップへ戻る