上野家のホームページ
ナーマル,マリン,ココ
[
新規
|
一覧
|
検索
|
最新
|
ヘルプ
]
開発/libusb
をテンプレートにして作成
資料室
開発/libusb をテンプレートにして作成
[
差分
|
バックアップ
|
リロード
]
[ ]
開始行:
* libusb
USBインターフェースを自作のハードウェア等で使用する場合,...
libusbはUSB機器をこのような用途で使うためのC言語用の汎用U...
デバイス毎に専用のデバイスドライバーを使わず,汎用のUSBデ...
libusbはLinux,BSD,Solaris,OS X,Windows,Androidなどの...
現在では開発は終了しているバージョンが0.1系と,開発が続け...
しかし,バージョン0.1系も現在でもよく使われている。~
** いろいろなWindows版libusb
libusbは,Linuxでのlibusb 0.1がWindowsに移植されたのが最...
*** libusb 0.1
Windows移植されたlibusb 0.1でWindows(98SE/ME,2000,XP,...
メンテナンスは[[こちらのサイト>https://sourceforge.net/pr...
現在はメンテナンスのみになっており,0.1.12が最終版でソフ...
USBの転送モードのアイソクロナス転送もサポートしている。~
フィルター・デバイスドライバーも用意されている。~
アプリケーションから多くのUSBデバイスへアクセスできる。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32bit), libusb0_x64.sys (64bit)
- ライブラリ~
ダイナミックライブラリ:libusb0.dll(32bit), libusb0_x64....
スタティックライブラリ:libusb.lib(msc), libusb.a(gcc)
- ヘッダーファイル~
lusb0_usb.h
バイナリ提供もある。~
Windowsでは,Windows 98seからWindows 7まで動作する。~
デバイスドライバーはデジタル署名がされていない。~
*** libusb 1.0 Windows
[[libusb 1.0 Windows>https://libusb.info/]]は使用するデバ...
デバイスドライバーにWinUSBを使うため,使える機能はWinUSB...
このため,アイソクロナス転送は使用できない。~
ファイル構成。~
- デバイスドライバー~
MicrosoftのWinUSBデバイスドライバーを使用。
- ライブラリ~
ダイナミックライブラリ:libusb-1.0.dll(msc 32bit,64bit),...
スタティックライブラリ:libusb-1.0.lib(msc 32bit,64bit),...
- ヘッダーファイル~
libusb.h
デバイスドライバーは標準でWindowsに付属している。~
*** libusb-win32
libusb-win32は,libusb 0.1完全互換性があるWindowsマシン用...
[[こちらで>http://libusb-win32.sourceforge.net]]もメンテ...
ファイル名などもlibusb 0.1系と同じ構成になっている。~
現在Windowsマシンにlibusbをインストールする場合は,このli...
フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32bit,64bit)~
- ライブラリ~
ダイナミックライブラリ:libusb0_x86.dll(32bit), libusb0....
スタティックライブラリ:libusb.lib(msc 32bit,64bit), lib...
- ヘッダーファイル~
lusb0_usb.h
デバイスドライバーはデジタル署名されているので,Windows10...
*** libusbK
libusbKは,libusb-win32を拡張してWinUSBのAPIをエミュレー...
libusb 1.0 Windows(WinUSBを使用する)では対応していない...
最新版はバージョン3.1.0.0。~
ファイル構成。~
- デバイスドライバー~
libusbK.sys (32bit,64bit)~
- ライブラリ~
ダイナミックライブラリ:libusbK.dll(32bit,64bit),libusb0...
スタティックライブラリ:libusbK.lib(32bit,64bit),libusb0...
- ヘッダーファイル~
libusbK.h
このため,0.1系と1.0系の両方のAPIを使用できるようになって...
デバイスドライバーはデジタル署名されているので,Windows10...
*** WinUSB
Microsoftが開発したlibusbのような汎用USBデバイスドライバ...
WDF(Windows Driver Foundation)である。~
Windows Vistaが発売されてからリリースされたが,Windows XP...
WinUSBは,カーネルモードで動作するWinUSB.sysというデバイ...
アプリケーションは,WinUSB APIを使ってUSBデバイスにアクセ...
WinUSBでサポートされる機能は,デバイス I/O 制御要求,リモ...
WinUSBはアイソクロナス転送をサポートしていないため,Webca...
デバイスドライバーはデジタル署名されていて,標準でWindows...
Windows RTでも使用できる。もちろん,Windowsマシン専用とな...
ビルドには,Windows Driver Kit(WDK)が必要。~
** その他の汎用USBライブラリ
*** usbdk
Windows用のライブラリ。~
ドライバやINFの作成と無関係に,USBシステムに直接アクセス...
libusb 1.0から見て,以前のlibusbフィルタドライバーの役目...
ビルドには,Windows Driver Kit(WDK)が必要。
*** USBD.DLL
極力シンプル化したUSB通信を行うためのデバイスドライバー。~
USBデバイスやパイプをオープンした後は,Windowsのファイル...
電子工作分野では人気であったが,最近は更新されていない。~
Windows 7 64bitで使用するには,非公式の64bit版を自己デジ...
*** USB Serial (CDC)
UARTのようなシリアルデバイス専用の汎用USBデバイスドライバ...
Windows 10では,Usbser.infが最初からインストールされてい...
なのでUSB機器がCDCデバイスクラスに属している場合は,自動...
この場合,独自のINFファイルを作成する必要はない。~
Windows 10以前の場合は,INFファイルを作成する必要がある。~
* ユーティリティツール
Windowsマシンでlibusb系のデバイスドライバーをインストール...
** Zadig
[[Zadig>https://zadig.akeo.ie/]]は,USB汎用デバイスドライ...
WinUSB,Libusb-Win32(libusb0.sys),libusbkなどをサポー...
デバイスメーカーからのネイティブなデバイスドライバーから...
対応している汎用USBデバイスドライバーは,~
- libusb-win32~
v1.4.0.0~
- WinUSB~
v6.1.7600.16385~
- libusbK~
v3.1.0.0~
- USB Serial (CDC)~
になっている。
* サンプルプログラム
** サンプルプログラム1
プロジェクトのフォルダに,64bit版のlibusb-1.0.libとlibusb...
''main.cpp''~
#code(c++,nonumber){{
#include <stdio.h>
#include "libusb.h"
#pragma comment(lib,"libusb-1.0.lib")
void die(char* s)
{
printf("Error: ");
puts(s);
exit(-1);
libusb_exit(NULL);
}
int main()
{
int ret;
//初期化
if ( libusb_init(NULL) < 0 )
die("libusb_init");
printf("Init\n");
//デバッグレベルの設定(通信失敗時などにメッセージが出る...
libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);
printf("Set debug\n");
//デバイスをVIDとPIDを指定してオープン
libusb_device_handle *devh = libusb_open_device_with_vid...
if ( devh == NULL)
die("libusb_open_device_with_vid_pid");
printf("libusb_open_device_with_vid_pid\n");
//デバイスのインターフェースの使用権を要求
//これをしないと、以降通信をしようとしても
//libusb: error [winusbx_submit_bulk_transfer] unable to...
//が出てしまいうまく行かない。
ret = libusb_claim_interface(devh,0);
if ( ret == 0 ) {
printf("OK\n");
} else if ( ret == LIBUSB_ERROR_NOT_FOUND )
die("libusb_claim_interface : LIBUSB_ERROR_NOT_FOUND");
else if ( ret == LIBUSB_ERROR_BUSY )
die("libusb_claim_interface : LIBUSB_ERROR_BUSY");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("llibusb_claim_interface : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_claim_interface : UNKNOWN %d");
printf("libusb_claim_interface\n");
//---
unsigned char data[64]={0x81};
int data_len=1;
//---
// EP=1にバルク送信。タイムアウト1000ms
ret = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_OUT | 1...
if ( ret == 0 ) {
printf("Received : %d Bytes\n", data_len);
for ( int i = 0; i<data_len; i++ ) {
printf("%02X ", data[i]);
}
} else if ( ret == LIBUSB_ERROR_TIMEOUT )
die("libusb_bulk_transfer : LIBUSB_ERROR_TIMEOUT");
else if ( ret == LIBUSB_ERROR_PIPE )
die("libusb_bulk_transfer : LIBUSB_ERROR_PIPE");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("libusb_bulk_transfer : LIBUSB_ERROR_OVERFLOW");
else if ( ret == LIBUSB_ERROR_NO_DEVICE )
die("libusb_bulk_transfer : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_bulk_transfer : UNKNOWN");
printf("\nSent\n");
//---
// EP=1からバルク受信。タイムアウト1000ms
ret = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_IN|1, d...
if(ret == 0) {
printf("Received : %d Bytes\n",data_len);
for(int i=0;i<data_len;i++ ) {
printf("%02X ",data[i]);
}
} else if ( ret == LIBUSB_ERROR_TIMEOUT )
die("libusb_bulk_transfer : LIBUSB_ERROR_TIMEOUT");
else if ( ret == LIBUSB_ERROR_PIPE )
die("libusb_bulk_transfer : LIBUSB_ERROR_PIPE");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("libusb_bulk_transfer : LIBUSB_ERROR_OVERFLOW");
else if ( ret == LIBUSB_ERROR_NO_DEVICE )
die("libusb_bulk_transfer : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_bulk_transfer : UNKNOWN");
printf("\nReceived\n");
//片付け
libusb_close(devh);
libusb_exit(NULL);
printf("Done\n");
return 0;
}
}}
** サンプルプログラム2
''main.cpp''
#code(c++,nonumber){{
#include <stdio.h>
#include "libusb.h"
#pragma comment(lib,"libusb-1.0.lib")
#define VENDERID 0x04D8
#define PRODUCTID 0x0053
#define EP1 0x1
int main()
{
libusb_device_handle *devh = NULL;
unsigned char send_data[64] = {0}; // マイコン側の受信...
unsigned char receive_data[64] = {0}; // マイコン側の送...
int data_len;
int r;
try {
//初期化
r = libusb_init(NULL);
if ( r < 0 )
throw(libusb_error_name(r));
//デバッグ設定
libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);
//デバイスハンドル取得
devh = libusb_open_device_with_vid_pid(NULL, VENDERID, ...
if ( devh == NULL )
throw("Device Not Found\n");
//使用権要求
r = libusb_claim_interface(devh, 0);
if ( r != 0 )
throw(libusb_error_name(r));
//送信
int dummy = 0;
send_data[0] = 0x81;
r = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_OUT | EP...
if ( r != 0 )
throw(libusb_error_name(r));
//受信
r = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_IN | EP1...
if ( r != 0 )
throw(libusb_error_name(r));
//受信データの表示
printf("Received : %d Bytes\n", data_len);
for ( int i = 0; i < data_len; i++ )
printf("%02X ", receive_data[i]);
printf("\n");
} catch ( const char* e ) {
//例外処理
printf(e);
}
//開放処理
if ( devh != NULL )
libusb_close(devh);
libusb_exit(NULL);
return 0;
}
}}
* プログラム全体の流れ
libusbではUSBデバイスを操作するアプリケーションは以下のよ...
- libusbを初期化(セッションを開く)
- 接続しているデバイスの一覧を取得
- 一覧の中から関心のあるデバイスを見つけて開く
- 開いたデバイスで何かする(メッセージをやり取りする)
- 開いたデバイスを閉じる
- デバイスの一覧を破棄する
- セッションを閉じる
それぞれの具体的な説明。
** libusbの初期化(セッションを開く)
初期化には,libusb_init()関数を使う。~
libusb_context *context;
libusb_init (&context);
libusbでは,単一のアプリケーションで複数のUSBとのやり取り...
その際,それぞれの状態はlibusb_contextという構造体型の変...
この変数によって区別されるlibusbの1つの実体が「セッション...
libusb_init()関数にもコンテキスト(へのポインタ(がある場...
ただし,ふつうはアプリケーションでlibusbを同時にいくつも...
libusb_init()の引数にNULLを指定すれば,このデフォルトのコ...
libusb_init (NULL);
** 接続しているデバイスの一覧を取得
libusbのセッションを初期化したら,USBポートに接続している...
そのために,まずはデバイスの一覧を取得する。これにはlibus...
libusb_get_device_list()関数の第1引数にはコンテキストを指...
第2引数には,デバイス一覧を格納する配列を指定する。~
libusbでは,個々のUSBデバイスをlibusb_deviceという構造体...
libusb_get_device_list()関数の返り値は,取得したデバイス...
以上より,デフォルトのコンテキストではこんな感じにデバイ...
libusb_device **list;
int cnt = libusb_get_device_list(NULL, &list);
** デバイス一覧から関心のあるデバイスを見つけて開く
libusb_get_device_list()関数で取得したデバイスの一覧のう...
走査にあたって目的のデバイスを特定する際には,USBの仕様で...
「デバイスのデスクリプタ」は,USBデバイスに関する一般的な...
libusbではlibusb_device_descriptorという構造体で表されて...
この構造体のフィールドは下記で参照できる。
http://libusb.sourceforge.net/api-1.0/structlibusb__devi...
libusb_device_descriptorのフィールドうち,デバイスを特定...
なお,USB-IFというのは''USB Implementers Forum''のことで...
|フィールド |説明 ...
|idVendor |USB-IFから割り当てられている識別子(Vendor...
|idProduct |Vendor IDを持っているベンダーが製品に割り...
|iManufacturer|ベンダーについて説明した文字列 ...
|iProduct |製品について説明した文字列 ...
デバイスを特定するには,取得したデバイス一覧に含まれてい...
デスクリプタの取り出しにはlibusb_get_device_descriptorと...
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
libusb_open(devive, &handle)
/* handle と desc を使って何かする */
...
}
上記には,libusb_device_handle型のhandleという変数へのポ...
デバイス一覧として得られるのがlibusb_device型の変数へのポ...
デスクリプタを参照する際も,libusb_device型の変数へのポイ...
じゃあ,libusb_device型の変数は何のためにあるかというと,...
参照カウンタは,デバイス一覧を取得した時点で「1」が割り当...
参照カウンタがゼロになったデバイスは,そのセッションで破...
ちなみに,Vendor IDとProduct IDを指定して一気にデバイスハ...
これにコンテキストとVendor IDとProduct IDを引数に指定して...
int vendorId, productId;
libusb_device_handle *handle;
handle = libusb_open_device_with_vid_pid(NULL, vendorId,...
** 開いたデバイスで何かする(メッセージをやり取りする)
デバイスハンドラとデスクリプタを手に入れたら,いよいよそ...
たとえば,iProductを標準出力に表示するなら全体はこんな感...
#include <stdio.h>
#include <libusb-1.0/libusb.h>
main () {
libusb_device **list;
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
int i, ret;
unsigned char text[512];
/* 初期化 */
libusb_init (NULL);
/* デバイスの一覧を取得 */
int cnt = libusb_get_device_list(NULL, &list); //
/* 一覧を走査して関心のあるデバイスを開く */
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
ret = libusb_open(devive, &handle)
/* handle と desc を使って何かする */
if (ret == 0) {
libusb_get_string_descriptor_ascii(
handle, desc.iProduct, text, sizeof(text));
printf ("%s\n", text);
}
}
/* クロージング */
...
}
libusb_get_string_descriptor_ascii()は,文字列のデスクリ...
USBの仕様では,iProductやiManufacturerのような文字列のデ...
この関数を使えば,取得したバイト列をそのままASCII文字列と...
あと上記で注意しないといけないのは,libusb_open()の戻り値...
もっとちゃんとしたエラー処理をするほうがよいだろうけど,...
** クロージング
終了は基本的に以下の手順に従う。
- 開いたデバイスを閉じる
- デバイスの一覧をクリアする
- セッションを閉じる
ただし,実行する関数はlibusb_free_device_list()とlibusb_e...
これは,libusb_free_device_list()の第2引数に1を設定するこ...
libusb_device型の変数の参照カウンタが減らず,生きたままに...
なお,libusb_exit()にはコンテキストを指定する必要がある(...
これはもちろんデフォルトのコンテキストを使っているならNUL...
全体はこんな感じになる。
#include <stdio.h>
#include <libusb-1.0/libusb.h>
main () {
libusb_device **list;
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
int i, ret;
unsigned char text[512];
/* 初期化 */
libusb_init (NULL);
/* デバイスの一覧を取得 */
int cnt = libusb_get_device_list(NULL, &list); //
/* 一覧を走査して関心のあるデバイスを開く */
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
ret = libusb_open(devive, &handle)
/* handle と desc を使って何かする */
if (ret == 0) {
libusb_get_string_descriptor_ascii(
handle, desc.iProduct, text, sizeof(text));
printf ("%s\n", text);
}
}
/* クロージング */
libusb_free_device_list(list, 1);
libusb_exit(NULL);
return 0;
}
「handleとdescを使って何かする」の部分でもっといろいろや...
これらの関数の使い方はUSBデバイスのほうの実装によるので,...
** コンパイルと実行
以下はDebianに自作のV-USB機器を指したときの例。~
$ gcc -O -Wall libusb-sample.c -lusb-1.0
$ ./a.out
Template
$
「Template」というのが,V-USBでデバイスを作ったときにデフ...
iProductが設定されているデバイスは意外と少ない。
終了行:
* libusb
USBインターフェースを自作のハードウェア等で使用する場合,...
libusbはUSB機器をこのような用途で使うためのC言語用の汎用U...
デバイス毎に専用のデバイスドライバーを使わず,汎用のUSBデ...
libusbはLinux,BSD,Solaris,OS X,Windows,Androidなどの...
現在では開発は終了しているバージョンが0.1系と,開発が続け...
しかし,バージョン0.1系も現在でもよく使われている。~
** いろいろなWindows版libusb
libusbは,Linuxでのlibusb 0.1がWindowsに移植されたのが最...
*** libusb 0.1
Windows移植されたlibusb 0.1でWindows(98SE/ME,2000,XP,...
メンテナンスは[[こちらのサイト>https://sourceforge.net/pr...
現在はメンテナンスのみになっており,0.1.12が最終版でソフ...
USBの転送モードのアイソクロナス転送もサポートしている。~
フィルター・デバイスドライバーも用意されている。~
アプリケーションから多くのUSBデバイスへアクセスできる。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32bit), libusb0_x64.sys (64bit)
- ライブラリ~
ダイナミックライブラリ:libusb0.dll(32bit), libusb0_x64....
スタティックライブラリ:libusb.lib(msc), libusb.a(gcc)
- ヘッダーファイル~
lusb0_usb.h
バイナリ提供もある。~
Windowsでは,Windows 98seからWindows 7まで動作する。~
デバイスドライバーはデジタル署名がされていない。~
*** libusb 1.0 Windows
[[libusb 1.0 Windows>https://libusb.info/]]は使用するデバ...
デバイスドライバーにWinUSBを使うため,使える機能はWinUSB...
このため,アイソクロナス転送は使用できない。~
ファイル構成。~
- デバイスドライバー~
MicrosoftのWinUSBデバイスドライバーを使用。
- ライブラリ~
ダイナミックライブラリ:libusb-1.0.dll(msc 32bit,64bit),...
スタティックライブラリ:libusb-1.0.lib(msc 32bit,64bit),...
- ヘッダーファイル~
libusb.h
デバイスドライバーは標準でWindowsに付属している。~
*** libusb-win32
libusb-win32は,libusb 0.1完全互換性があるWindowsマシン用...
[[こちらで>http://libusb-win32.sourceforge.net]]もメンテ...
ファイル名などもlibusb 0.1系と同じ構成になっている。~
現在Windowsマシンにlibusbをインストールする場合は,このli...
フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32bit,64bit)~
- ライブラリ~
ダイナミックライブラリ:libusb0_x86.dll(32bit), libusb0....
スタティックライブラリ:libusb.lib(msc 32bit,64bit), lib...
- ヘッダーファイル~
lusb0_usb.h
デバイスドライバーはデジタル署名されているので,Windows10...
*** libusbK
libusbKは,libusb-win32を拡張してWinUSBのAPIをエミュレー...
libusb 1.0 Windows(WinUSBを使用する)では対応していない...
最新版はバージョン3.1.0.0。~
ファイル構成。~
- デバイスドライバー~
libusbK.sys (32bit,64bit)~
- ライブラリ~
ダイナミックライブラリ:libusbK.dll(32bit,64bit),libusb0...
スタティックライブラリ:libusbK.lib(32bit,64bit),libusb0...
- ヘッダーファイル~
libusbK.h
このため,0.1系と1.0系の両方のAPIを使用できるようになって...
デバイスドライバーはデジタル署名されているので,Windows10...
*** WinUSB
Microsoftが開発したlibusbのような汎用USBデバイスドライバ...
WDF(Windows Driver Foundation)である。~
Windows Vistaが発売されてからリリースされたが,Windows XP...
WinUSBは,カーネルモードで動作するWinUSB.sysというデバイ...
アプリケーションは,WinUSB APIを使ってUSBデバイスにアクセ...
WinUSBでサポートされる機能は,デバイス I/O 制御要求,リモ...
WinUSBはアイソクロナス転送をサポートしていないため,Webca...
デバイスドライバーはデジタル署名されていて,標準でWindows...
Windows RTでも使用できる。もちろん,Windowsマシン専用とな...
ビルドには,Windows Driver Kit(WDK)が必要。~
** その他の汎用USBライブラリ
*** usbdk
Windows用のライブラリ。~
ドライバやINFの作成と無関係に,USBシステムに直接アクセス...
libusb 1.0から見て,以前のlibusbフィルタドライバーの役目...
ビルドには,Windows Driver Kit(WDK)が必要。
*** USBD.DLL
極力シンプル化したUSB通信を行うためのデバイスドライバー。~
USBデバイスやパイプをオープンした後は,Windowsのファイル...
電子工作分野では人気であったが,最近は更新されていない。~
Windows 7 64bitで使用するには,非公式の64bit版を自己デジ...
*** USB Serial (CDC)
UARTのようなシリアルデバイス専用の汎用USBデバイスドライバ...
Windows 10では,Usbser.infが最初からインストールされてい...
なのでUSB機器がCDCデバイスクラスに属している場合は,自動...
この場合,独自のINFファイルを作成する必要はない。~
Windows 10以前の場合は,INFファイルを作成する必要がある。~
* ユーティリティツール
Windowsマシンでlibusb系のデバイスドライバーをインストール...
** Zadig
[[Zadig>https://zadig.akeo.ie/]]は,USB汎用デバイスドライ...
WinUSB,Libusb-Win32(libusb0.sys),libusbkなどをサポー...
デバイスメーカーからのネイティブなデバイスドライバーから...
対応している汎用USBデバイスドライバーは,~
- libusb-win32~
v1.4.0.0~
- WinUSB~
v6.1.7600.16385~
- libusbK~
v3.1.0.0~
- USB Serial (CDC)~
になっている。
* サンプルプログラム
** サンプルプログラム1
プロジェクトのフォルダに,64bit版のlibusb-1.0.libとlibusb...
''main.cpp''~
#code(c++,nonumber){{
#include <stdio.h>
#include "libusb.h"
#pragma comment(lib,"libusb-1.0.lib")
void die(char* s)
{
printf("Error: ");
puts(s);
exit(-1);
libusb_exit(NULL);
}
int main()
{
int ret;
//初期化
if ( libusb_init(NULL) < 0 )
die("libusb_init");
printf("Init\n");
//デバッグレベルの設定(通信失敗時などにメッセージが出る...
libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);
printf("Set debug\n");
//デバイスをVIDとPIDを指定してオープン
libusb_device_handle *devh = libusb_open_device_with_vid...
if ( devh == NULL)
die("libusb_open_device_with_vid_pid");
printf("libusb_open_device_with_vid_pid\n");
//デバイスのインターフェースの使用権を要求
//これをしないと、以降通信をしようとしても
//libusb: error [winusbx_submit_bulk_transfer] unable to...
//が出てしまいうまく行かない。
ret = libusb_claim_interface(devh,0);
if ( ret == 0 ) {
printf("OK\n");
} else if ( ret == LIBUSB_ERROR_NOT_FOUND )
die("libusb_claim_interface : LIBUSB_ERROR_NOT_FOUND");
else if ( ret == LIBUSB_ERROR_BUSY )
die("libusb_claim_interface : LIBUSB_ERROR_BUSY");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("llibusb_claim_interface : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_claim_interface : UNKNOWN %d");
printf("libusb_claim_interface\n");
//---
unsigned char data[64]={0x81};
int data_len=1;
//---
// EP=1にバルク送信。タイムアウト1000ms
ret = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_OUT | 1...
if ( ret == 0 ) {
printf("Received : %d Bytes\n", data_len);
for ( int i = 0; i<data_len; i++ ) {
printf("%02X ", data[i]);
}
} else if ( ret == LIBUSB_ERROR_TIMEOUT )
die("libusb_bulk_transfer : LIBUSB_ERROR_TIMEOUT");
else if ( ret == LIBUSB_ERROR_PIPE )
die("libusb_bulk_transfer : LIBUSB_ERROR_PIPE");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("libusb_bulk_transfer : LIBUSB_ERROR_OVERFLOW");
else if ( ret == LIBUSB_ERROR_NO_DEVICE )
die("libusb_bulk_transfer : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_bulk_transfer : UNKNOWN");
printf("\nSent\n");
//---
// EP=1からバルク受信。タイムアウト1000ms
ret = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_IN|1, d...
if(ret == 0) {
printf("Received : %d Bytes\n",data_len);
for(int i=0;i<data_len;i++ ) {
printf("%02X ",data[i]);
}
} else if ( ret == LIBUSB_ERROR_TIMEOUT )
die("libusb_bulk_transfer : LIBUSB_ERROR_TIMEOUT");
else if ( ret == LIBUSB_ERROR_PIPE )
die("libusb_bulk_transfer : LIBUSB_ERROR_PIPE");
else if ( ret == LIBUSB_ERROR_OVERFLOW )
die("libusb_bulk_transfer : LIBUSB_ERROR_OVERFLOW");
else if ( ret == LIBUSB_ERROR_NO_DEVICE )
die("libusb_bulk_transfer : LIBUSB_ERROR_NO_DEVICE");
else
die("libusb_bulk_transfer : UNKNOWN");
printf("\nReceived\n");
//片付け
libusb_close(devh);
libusb_exit(NULL);
printf("Done\n");
return 0;
}
}}
** サンプルプログラム2
''main.cpp''
#code(c++,nonumber){{
#include <stdio.h>
#include "libusb.h"
#pragma comment(lib,"libusb-1.0.lib")
#define VENDERID 0x04D8
#define PRODUCTID 0x0053
#define EP1 0x1
int main()
{
libusb_device_handle *devh = NULL;
unsigned char send_data[64] = {0}; // マイコン側の受信...
unsigned char receive_data[64] = {0}; // マイコン側の送...
int data_len;
int r;
try {
//初期化
r = libusb_init(NULL);
if ( r < 0 )
throw(libusb_error_name(r));
//デバッグ設定
libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);
//デバイスハンドル取得
devh = libusb_open_device_with_vid_pid(NULL, VENDERID, ...
if ( devh == NULL )
throw("Device Not Found\n");
//使用権要求
r = libusb_claim_interface(devh, 0);
if ( r != 0 )
throw(libusb_error_name(r));
//送信
int dummy = 0;
send_data[0] = 0x81;
r = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_OUT | EP...
if ( r != 0 )
throw(libusb_error_name(r));
//受信
r = libusb_bulk_transfer(devh, LIBUSB_ENDPOINT_IN | EP1...
if ( r != 0 )
throw(libusb_error_name(r));
//受信データの表示
printf("Received : %d Bytes\n", data_len);
for ( int i = 0; i < data_len; i++ )
printf("%02X ", receive_data[i]);
printf("\n");
} catch ( const char* e ) {
//例外処理
printf(e);
}
//開放処理
if ( devh != NULL )
libusb_close(devh);
libusb_exit(NULL);
return 0;
}
}}
* プログラム全体の流れ
libusbではUSBデバイスを操作するアプリケーションは以下のよ...
- libusbを初期化(セッションを開く)
- 接続しているデバイスの一覧を取得
- 一覧の中から関心のあるデバイスを見つけて開く
- 開いたデバイスで何かする(メッセージをやり取りする)
- 開いたデバイスを閉じる
- デバイスの一覧を破棄する
- セッションを閉じる
それぞれの具体的な説明。
** libusbの初期化(セッションを開く)
初期化には,libusb_init()関数を使う。~
libusb_context *context;
libusb_init (&context);
libusbでは,単一のアプリケーションで複数のUSBとのやり取り...
その際,それぞれの状態はlibusb_contextという構造体型の変...
この変数によって区別されるlibusbの1つの実体が「セッション...
libusb_init()関数にもコンテキスト(へのポインタ(がある場...
ただし,ふつうはアプリケーションでlibusbを同時にいくつも...
libusb_init()の引数にNULLを指定すれば,このデフォルトのコ...
libusb_init (NULL);
** 接続しているデバイスの一覧を取得
libusbのセッションを初期化したら,USBポートに接続している...
そのために,まずはデバイスの一覧を取得する。これにはlibus...
libusb_get_device_list()関数の第1引数にはコンテキストを指...
第2引数には,デバイス一覧を格納する配列を指定する。~
libusbでは,個々のUSBデバイスをlibusb_deviceという構造体...
libusb_get_device_list()関数の返り値は,取得したデバイス...
以上より,デフォルトのコンテキストではこんな感じにデバイ...
libusb_device **list;
int cnt = libusb_get_device_list(NULL, &list);
** デバイス一覧から関心のあるデバイスを見つけて開く
libusb_get_device_list()関数で取得したデバイスの一覧のう...
走査にあたって目的のデバイスを特定する際には,USBの仕様で...
「デバイスのデスクリプタ」は,USBデバイスに関する一般的な...
libusbではlibusb_device_descriptorという構造体で表されて...
この構造体のフィールドは下記で参照できる。
http://libusb.sourceforge.net/api-1.0/structlibusb__devi...
libusb_device_descriptorのフィールドうち,デバイスを特定...
なお,USB-IFというのは''USB Implementers Forum''のことで...
|フィールド |説明 ...
|idVendor |USB-IFから割り当てられている識別子(Vendor...
|idProduct |Vendor IDを持っているベンダーが製品に割り...
|iManufacturer|ベンダーについて説明した文字列 ...
|iProduct |製品について説明した文字列 ...
デバイスを特定するには,取得したデバイス一覧に含まれてい...
デスクリプタの取り出しにはlibusb_get_device_descriptorと...
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
libusb_open(devive, &handle)
/* handle と desc を使って何かする */
...
}
上記には,libusb_device_handle型のhandleという変数へのポ...
デバイス一覧として得られるのがlibusb_device型の変数へのポ...
デスクリプタを参照する際も,libusb_device型の変数へのポイ...
じゃあ,libusb_device型の変数は何のためにあるかというと,...
参照カウンタは,デバイス一覧を取得した時点で「1」が割り当...
参照カウンタがゼロになったデバイスは,そのセッションで破...
ちなみに,Vendor IDとProduct IDを指定して一気にデバイスハ...
これにコンテキストとVendor IDとProduct IDを引数に指定して...
int vendorId, productId;
libusb_device_handle *handle;
handle = libusb_open_device_with_vid_pid(NULL, vendorId,...
** 開いたデバイスで何かする(メッセージをやり取りする)
デバイスハンドラとデスクリプタを手に入れたら,いよいよそ...
たとえば,iProductを標準出力に表示するなら全体はこんな感...
#include <stdio.h>
#include <libusb-1.0/libusb.h>
main () {
libusb_device **list;
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
int i, ret;
unsigned char text[512];
/* 初期化 */
libusb_init (NULL);
/* デバイスの一覧を取得 */
int cnt = libusb_get_device_list(NULL, &list); //
/* 一覧を走査して関心のあるデバイスを開く */
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
ret = libusb_open(devive, &handle)
/* handle と desc を使って何かする */
if (ret == 0) {
libusb_get_string_descriptor_ascii(
handle, desc.iProduct, text, sizeof(text));
printf ("%s\n", text);
}
}
/* クロージング */
...
}
libusb_get_string_descriptor_ascii()は,文字列のデスクリ...
USBの仕様では,iProductやiManufacturerのような文字列のデ...
この関数を使えば,取得したバイト列をそのままASCII文字列と...
あと上記で注意しないといけないのは,libusb_open()の戻り値...
もっとちゃんとしたエラー処理をするほうがよいだろうけど,...
** クロージング
終了は基本的に以下の手順に従う。
- 開いたデバイスを閉じる
- デバイスの一覧をクリアする
- セッションを閉じる
ただし,実行する関数はlibusb_free_device_list()とlibusb_e...
これは,libusb_free_device_list()の第2引数に1を設定するこ...
libusb_device型の変数の参照カウンタが減らず,生きたままに...
なお,libusb_exit()にはコンテキストを指定する必要がある(...
これはもちろんデフォルトのコンテキストを使っているならNUL...
全体はこんな感じになる。
#include <stdio.h>
#include <libusb-1.0/libusb.h>
main () {
libusb_device **list;
struct libusb_device_descriptor desc;
libusb_device_handle *handle;
int i, ret;
unsigned char text[512];
/* 初期化 */
libusb_init (NULL);
/* デバイスの一覧を取得 */
int cnt = libusb_get_device_list(NULL, &list); //
/* 一覧を走査して関心のあるデバイスを開く */
for (i = 0; i < cnt; i++) {
libusb_device *dev = list[i];
libusb_get_device_descriptor(device, &desc);
ret = libusb_open(devive, &handle)
/* handle と desc を使って何かする */
if (ret == 0) {
libusb_get_string_descriptor_ascii(
handle, desc.iProduct, text, sizeof(text));
printf ("%s\n", text);
}
}
/* クロージング */
libusb_free_device_list(list, 1);
libusb_exit(NULL);
return 0;
}
「handleとdescを使って何かする」の部分でもっといろいろや...
これらの関数の使い方はUSBデバイスのほうの実装によるので,...
** コンパイルと実行
以下はDebianに自作のV-USB機器を指したときの例。~
$ gcc -O -Wall libusb-sample.c -lusb-1.0
$ ./a.out
Template
$
「Template」というのが,V-USBでデバイスを作ったときにデフ...
iProductが設定されているデバイスは意外と少ない。
ページ名:
Counter: 0, today: 0, yesterday: 0
Copyright©2008 Yuji Ueno All Rights Reserved.
ログイン
ユーザ名:
パスワード:
IDとパスワードを記憶
パスワード紛失
メインメニュー
ホーム
でぶlog
資料室
最新ページ一覧
全ページ一覧
ヘルプ
フォーラム
お問い合わせ