上野家のホームページ
ナーマル,マリン,ココ
[
新規
|
一覧
|
検索
|
最新
|
ヘルプ
]
開発/libusb
をテンプレートにして作成
資料室
開発/libusb をテンプレートにして作成
[
差分
|
バックアップ
|
リロード
]
[ ]
開始行:
* libusb(汎用USBライブラリ)
USBインターフェースを自作のハードウェア等で使用する場合,...
libusbはUSB機器をこのような用途で使うためのC言語用の汎用U...
デバイス毎に専用のデバイスドライバーを使わず,汎用のUSBデ...
libusbはLinux,BSD,Solaris,OS X,Windows,Androidなどの...
現在では開発は終了しているバージョンが0.1と,開発が続けら...
しかし,バージョン0.1も使われている。~
** いろいろなlibusbとWindows版
libusbはLinuxマシンでのlibusb 0.1が開発され,その後それが...
そこからさらに派生したいくつか種類がある。~
また,2005年にMicrosoftはよく知られているUSBのクラスドラ...
そこでMicrosoftもlibusbのようなWinUSBと呼ばれる独自のデバ...
Windowsマシンではこのような経緯により,USBデバイスに汎用U...
*** libusb 0.1
[[libusb 0.1>http://libusb.org/]]はLinuxマシンでUSB機器と...
クロスプラットフォーム(Linuxやmac OS X,Windows)で動作...
アプリケーションから多くのUSBデバイスへ容易にアクセスでき...
メンテナンスは[[こちらのサイト>https://sourceforge.net/pr...
現在はメンテナンスのみになっており''0.1.12''が最終版でソ...
libusb 0.1ではUSBの転送モードの一つであるアイソクロナス転...
また,フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (win 32bit), libusb0_x64.sys (win 64bit)
- ライブラリ~
ダイナミックライブラリ:libusb.so(linux),libusb0.dll(win...
スタティックライブラリ:libusb.a(linux, win gcc), libusb...
- ヘッダーファイル~
usb.h(linux), lusb0_usb.h(windows)
バイナリ提供もある。~
デバイスドライバーにはデジタル署名がされていない。なのでW...
*** libusb 1.0
libusb 0.1に変わって開発されている[[libusb 1.0>https://li...
また,Windowsマシンにも移植されている。~
メンテナンスは[[こちら>https://github.com/libusb/libusb]]...
[[libusb 1.0 API>https://libusb.sourceforge.io/api-1.0/]]...
このため,[[libusb-compat-0.1 wrapper>https://github.com/...
libusb 1.0では独自にデバイスドライバーを開発せず,Windows...
Windows版でWinUSBのデバイスドライバーを使っているので,機...
ファイル構成。~
- デバイスドライバー~
WinUSB.sys (32bit,64bit) (Microsoftの汎用USBデバイスド...
- ライブラリ~
ダイナミックライブラリ:libusb-1.0.so(linux), libusb-1.0...
スタティックライブラリ:libusb-1.0.a(linux, win gcc 32/6...
- ヘッダーファイル~
libusb.h
Windows用のデバイスドライバーは,標準でWindowsに付属して...
Linux等のデバイスドライバーは,標準で用意されているlibusb...
*** libusb-win32
[[libusb-win32>http://libusb-win32.sourceforge.net]]は,l...
libusb 0.1は開発が終了してしまったので,Windows 10以降の...
[[こちらで>https://github.com/mcuee/libusb-win32]]メンテ...
ファイル名などもlibusb 0.1と同じ構成になっている。~
また,フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32/64bit)
- ライブラリ~
ダイナミックライブラリ:libusb0_x86.dll(32bit), libusb0....
スタティックライブラリ:libusb.lib(msc 32/64bit), libusb...
- ヘッダーファイル~
lusb0_usb.h
デバイスドライバーはデジタル署名されているので,Windows10...
*** libusbK
[[libusbK>https://sourceforge.net/projects/libusbk/]]はベ...
Windows版libusb 1.0(WinUSBデバイスドライバーを使用する)...
最新版はバージョン''3.1.0.0''。[[こちらから>https://githu...
ファイル構成。~
- デバイスドライバー~
libusbK.sys (32bit,64bit)
- ライブラリ~
ダイナミックライブラリ:libusbK.dll(32/64bit),libusb0_dl...
スタティックライブラリ:libusbK.lib(32/64bit),libusb0.li...
- ヘッダーファイル~
libusbK.h
libusbKでは0.1系と1.0系の両方のAPIを使用できるようになっ...
デバイスドライバーはデジタル署名されているので,Windows10...
*** WinUSB
Microsoftが開発したlibusbのようなWindowsの汎用USBデバイス...
WDF(Windows Driver Foundation)である。~
Windows Vistaが発売されてからリリースされたが,Windows XP...
WinUSBはカーネルモードで動作する''WinUSB.sys''デバイスド...
アプリケーションはWinUSB API(WinUSB.dll)を使ってUSBデバ...
WinUSBでサポートされる機能は,デバイスI/O制御要求,リモー...
WinUSBはアイソクロナス転送をサポートしていないため,Webca...
デバイスドライバーはデジタル署名されていて,標準でWindows...
ただWindowsマシン専用となる。~
ビルドには[[Windows Driver Kit(WDK)>https://learn.micro...
ファイル構成。~
- デバイスドライバー~
WinUSB.sys (32bit,64bit)
- ライブラリ~
ダイナミックライブラリ:WinUSB.dll (msc 32bit,64bit)
スタティックライブラリ:WinUSB.lib (msc 32bit,64bit)
- ヘッダーファイル~
winusb.h (msc)
** その他の汎用USBライブラリ
*** usbdk
[[usbdk>https://github.com/daynix/UsbDk]](USB Developmen...
ドライバやINFの作成と無関係に,USBシステムに直接アクセス...
libusb 1.0から見て,以前のlibusbフィルタドライバーの役目...
ビルドには,Visual StudioとWindows Driver Kit(WDK)やWin...
[[インストーラー>https://github.com/daynix/UsbDk/releases...
*** USBD.DLL
[[USBD.DLL>http://www.otto.to/~kasiwano/]]は極力シンプル...
USBデバイスやパイプをオープンした後は,Windowsのファイル...
電子工作分野では人気であったが,最近は更新されていない。~
Windows 7 64bitで使用するには,非公式の64bit版を自己デジ...
[[汎用USBドライバの使い方>http://www.picfun.com/usb07.htm...
*** USB Serial (CDC)
USB Serial (CDC)(Universal Serial Bus Communications Dev...
Windows 10では,Usbser.sys/Usbser.infが最初からインストー...
なので,USB機器がCDCデバイスクラスに属している場合は,こ...
この場合,独自のINFファイルを作成する必要はない。~
Windows 10以前の場合は,INFファイルを作成する必要がある。~
* ユーティリティツール
Windowsマシンでlibusb系のデバイスドライバーをインストール...
** Zadig
[[Zadig>https://zadig.akeo.ie/]]は,USB汎用デバイスドライ...
WinUSB,libusb-win32,libusbKなどをサポートしている。~
デバイスから情報を読み取って,汎用USBデバイスドライバーの...
バージョン2.9で対応している汎用USBデバイスドライバーは,~
- libusb-win32~
v1.4.0.0~
- WinUSB~
v6.1.7600.16385~
- libusbK~
v3.1.0.0~
- USB Serial (CDC)~
になっている。
* libusbの使い方
** サンプルプログラム1
ワークディレクトリに64bit版のlibusb-1.0.libとlibusb-1.0.d...
''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 t...
// が出てしまいうまく行かない。
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ポートに接続している...
そのために,まずはデバイスの一覧を取得する。~
これにはlibusb_get_device_list()関数を使う。~
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デバイスの一般的な情報で,USB ...
libusbではlibusb_device_descriptorという構造体に格納され...
この構造体のフィールドは[[ここ>http://libusb.sourceforge....
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)
// 以下処理
...
}
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);
// デバイスをOpen
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_open()はデバ...
*** 終了
終了は基本的に以下の手順に従う。
+ 開いたデバイスを閉じる
+ デバイスの一覧をクリアする
+ セッションを閉じる
ただし,実行する関数はlibusb_free_device_list()とlibusb_e...
これはlibusb_free_device_list()の第2引数に1にすると,上記...
libusb_device型の変数の参照カウンタが減らず,生きたままに...
なお,libusb_exit()にはコンテキストを指定する必要がある(...
デフォルトのコンテキストを使っているならNULLでいい。~
全体はこんなようになる。
#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を使って通信する」の部分では,libusb_contro...
//** コンパイルと実行 [#t952ecaf]
//以下はDebianに自作のV-USB機器を指したときの例。~
// $ gcc -O -Wall libusb-sample.c -lusb-1.0
// $ ./a.out
// Template
//
// $
//
//「Template」というのが,V-USBでデバイスを作ったときにデ...
//iProductが設定されているデバイスは意外と少ない。
終了行:
* libusb(汎用USBライブラリ)
USBインターフェースを自作のハードウェア等で使用する場合,...
libusbはUSB機器をこのような用途で使うためのC言語用の汎用U...
デバイス毎に専用のデバイスドライバーを使わず,汎用のUSBデ...
libusbはLinux,BSD,Solaris,OS X,Windows,Androidなどの...
現在では開発は終了しているバージョンが0.1と,開発が続けら...
しかし,バージョン0.1も使われている。~
** いろいろなlibusbとWindows版
libusbはLinuxマシンでのlibusb 0.1が開発され,その後それが...
そこからさらに派生したいくつか種類がある。~
また,2005年にMicrosoftはよく知られているUSBのクラスドラ...
そこでMicrosoftもlibusbのようなWinUSBと呼ばれる独自のデバ...
Windowsマシンではこのような経緯により,USBデバイスに汎用U...
*** libusb 0.1
[[libusb 0.1>http://libusb.org/]]はLinuxマシンでUSB機器と...
クロスプラットフォーム(Linuxやmac OS X,Windows)で動作...
アプリケーションから多くのUSBデバイスへ容易にアクセスでき...
メンテナンスは[[こちらのサイト>https://sourceforge.net/pr...
現在はメンテナンスのみになっており''0.1.12''が最終版でソ...
libusb 0.1ではUSBの転送モードの一つであるアイソクロナス転...
また,フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (win 32bit), libusb0_x64.sys (win 64bit)
- ライブラリ~
ダイナミックライブラリ:libusb.so(linux),libusb0.dll(win...
スタティックライブラリ:libusb.a(linux, win gcc), libusb...
- ヘッダーファイル~
usb.h(linux), lusb0_usb.h(windows)
バイナリ提供もある。~
デバイスドライバーにはデジタル署名がされていない。なのでW...
*** libusb 1.0
libusb 0.1に変わって開発されている[[libusb 1.0>https://li...
また,Windowsマシンにも移植されている。~
メンテナンスは[[こちら>https://github.com/libusb/libusb]]...
[[libusb 1.0 API>https://libusb.sourceforge.io/api-1.0/]]...
このため,[[libusb-compat-0.1 wrapper>https://github.com/...
libusb 1.0では独自にデバイスドライバーを開発せず,Windows...
Windows版でWinUSBのデバイスドライバーを使っているので,機...
ファイル構成。~
- デバイスドライバー~
WinUSB.sys (32bit,64bit) (Microsoftの汎用USBデバイスド...
- ライブラリ~
ダイナミックライブラリ:libusb-1.0.so(linux), libusb-1.0...
スタティックライブラリ:libusb-1.0.a(linux, win gcc 32/6...
- ヘッダーファイル~
libusb.h
Windows用のデバイスドライバーは,標準でWindowsに付属して...
Linux等のデバイスドライバーは,標準で用意されているlibusb...
*** libusb-win32
[[libusb-win32>http://libusb-win32.sourceforge.net]]は,l...
libusb 0.1は開発が終了してしまったので,Windows 10以降の...
[[こちらで>https://github.com/mcuee/libusb-win32]]メンテ...
ファイル名などもlibusb 0.1と同じ構成になっている。~
また,フィルター・デバイスドライバーも用意されている。~
ファイル構成。~
- デバイスドライバー~
libusb0.sys (32/64bit)
- ライブラリ~
ダイナミックライブラリ:libusb0_x86.dll(32bit), libusb0....
スタティックライブラリ:libusb.lib(msc 32/64bit), libusb...
- ヘッダーファイル~
lusb0_usb.h
デバイスドライバーはデジタル署名されているので,Windows10...
*** libusbK
[[libusbK>https://sourceforge.net/projects/libusbk/]]はベ...
Windows版libusb 1.0(WinUSBデバイスドライバーを使用する)...
最新版はバージョン''3.1.0.0''。[[こちらから>https://githu...
ファイル構成。~
- デバイスドライバー~
libusbK.sys (32bit,64bit)
- ライブラリ~
ダイナミックライブラリ:libusbK.dll(32/64bit),libusb0_dl...
スタティックライブラリ:libusbK.lib(32/64bit),libusb0.li...
- ヘッダーファイル~
libusbK.h
libusbKでは0.1系と1.0系の両方のAPIを使用できるようになっ...
デバイスドライバーはデジタル署名されているので,Windows10...
*** WinUSB
Microsoftが開発したlibusbのようなWindowsの汎用USBデバイス...
WDF(Windows Driver Foundation)である。~
Windows Vistaが発売されてからリリースされたが,Windows XP...
WinUSBはカーネルモードで動作する''WinUSB.sys''デバイスド...
アプリケーションはWinUSB API(WinUSB.dll)を使ってUSBデバ...
WinUSBでサポートされる機能は,デバイスI/O制御要求,リモー...
WinUSBはアイソクロナス転送をサポートしていないため,Webca...
デバイスドライバーはデジタル署名されていて,標準でWindows...
ただWindowsマシン専用となる。~
ビルドには[[Windows Driver Kit(WDK)>https://learn.micro...
ファイル構成。~
- デバイスドライバー~
WinUSB.sys (32bit,64bit)
- ライブラリ~
ダイナミックライブラリ:WinUSB.dll (msc 32bit,64bit)
スタティックライブラリ:WinUSB.lib (msc 32bit,64bit)
- ヘッダーファイル~
winusb.h (msc)
** その他の汎用USBライブラリ
*** usbdk
[[usbdk>https://github.com/daynix/UsbDk]](USB Developmen...
ドライバやINFの作成と無関係に,USBシステムに直接アクセス...
libusb 1.0から見て,以前のlibusbフィルタドライバーの役目...
ビルドには,Visual StudioとWindows Driver Kit(WDK)やWin...
[[インストーラー>https://github.com/daynix/UsbDk/releases...
*** USBD.DLL
[[USBD.DLL>http://www.otto.to/~kasiwano/]]は極力シンプル...
USBデバイスやパイプをオープンした後は,Windowsのファイル...
電子工作分野では人気であったが,最近は更新されていない。~
Windows 7 64bitで使用するには,非公式の64bit版を自己デジ...
[[汎用USBドライバの使い方>http://www.picfun.com/usb07.htm...
*** USB Serial (CDC)
USB Serial (CDC)(Universal Serial Bus Communications Dev...
Windows 10では,Usbser.sys/Usbser.infが最初からインストー...
なので,USB機器がCDCデバイスクラスに属している場合は,こ...
この場合,独自のINFファイルを作成する必要はない。~
Windows 10以前の場合は,INFファイルを作成する必要がある。~
* ユーティリティツール
Windowsマシンでlibusb系のデバイスドライバーをインストール...
** Zadig
[[Zadig>https://zadig.akeo.ie/]]は,USB汎用デバイスドライ...
WinUSB,libusb-win32,libusbKなどをサポートしている。~
デバイスから情報を読み取って,汎用USBデバイスドライバーの...
バージョン2.9で対応している汎用USBデバイスドライバーは,~
- libusb-win32~
v1.4.0.0~
- WinUSB~
v6.1.7600.16385~
- libusbK~
v3.1.0.0~
- USB Serial (CDC)~
になっている。
* libusbの使い方
** サンプルプログラム1
ワークディレクトリに64bit版のlibusb-1.0.libとlibusb-1.0.d...
''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 t...
// が出てしまいうまく行かない。
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ポートに接続している...
そのために,まずはデバイスの一覧を取得する。~
これにはlibusb_get_device_list()関数を使う。~
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デバイスの一般的な情報で,USB ...
libusbではlibusb_device_descriptorという構造体に格納され...
この構造体のフィールドは[[ここ>http://libusb.sourceforge....
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)
// 以下処理
...
}
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);
// デバイスをOpen
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_open()はデバ...
*** 終了
終了は基本的に以下の手順に従う。
+ 開いたデバイスを閉じる
+ デバイスの一覧をクリアする
+ セッションを閉じる
ただし,実行する関数はlibusb_free_device_list()とlibusb_e...
これはlibusb_free_device_list()の第2引数に1にすると,上記...
libusb_device型の変数の参照カウンタが減らず,生きたままに...
なお,libusb_exit()にはコンテキストを指定する必要がある(...
デフォルトのコンテキストを使っているならNULLでいい。~
全体はこんなようになる。
#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を使って通信する」の部分では,libusb_contro...
//** コンパイルと実行 [#t952ecaf]
//以下は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
資料室
最新ページ一覧
全ページ一覧
ヘルプ
フォーラム
お問い合わせ