Top > libusbについて

広告

libusb」は簡単にUSB機器にアクセスできるように作られたC言語用ライブラリ。
カーネルの変更や専用のドライバを必要としないので開発は楽。
Windows版も存在する

--目次--

準備

  • libusb」がインストールされていなかったらインストールする。
    • さまざまなディストリビューションにパッケージが用意されているので、インストールは簡単。
  • アクセスするUSB機器のベンダーIDとプロダクトIDを調べる。機器の説明書や仕様書に載っている。
    • 分からなかったらつなげてみて「lsusb」コマンドを実行。(Debianではusbutilsパッケージに含まれる)
      Bus 001 Device 001: ID 0123:4567
      というように表示され、IDの後に続く最初の4桁(この場合0123)がベンダーID、後の4桁がプロダクトID(この場合4567)になる。
  • rootでないとデバイスにアクセスできない場合があるので注意。
    • 筆者はしばらくこれにはまった (^^;

プログラミング(はじめの方)

USBの機器にあまり依存しない部分

インクルード

libusb用のヘッダーをincludeする

#include <usb.h>

という行を入れる

変数の定義

USB用に使う変数を宣言

struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *dh;

初期化

あまり考えずに以下の行を書き込む

usb_init();
usb_find_busses();
usb_find_devices();

デバイスを見つける

デバイスがつながっているか見つける。「VENDOR_ID」と「PRODUCT_ID」にベンダーIDとプロダクトIDを入れておく。

for (bus = usb_get_busses(); bus; bus = bus->next) {
   for (dev = bus->devices; dev; dev = dev->next) {
	if (dev->descriptor.idVendor == VENDOR_ID &&
	    dev->descriptor.idProduct == PRODUCT_ID) {
	    goto device_found;
	}
   }
}
/* デバイスが見つからなかった場合 */
fprintf(stderr, "Device not found.\n");
exit(1);
/* デバイスが見つかった場合 */
device_found:
printf("Device Found!!\n"); /* 確認用*/

デバイスを開く

単純には

/*USB Open*/
dh = usb_open(dev);

エラートラップを付ける

if( (dh=usb_open(dev))==NULL ){
  printf("usb_open Error.(%s)\n",usb_strerror());
  exit(1);
}

最後に「usb_close」で閉じることを忘れない

usb_close(dh);

デバイスを閉めておかないと次回プログラムを起動したときにちゃんと動かない。

コンフィグレーションやインターフェースの要求

if(usb_set_configuration(dh,dev->config->bConfigurationValue)<0){
       if(usb_detach_kernel_driver_np(dh,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
           printf("usb_set_configuration Error.\n");
           printf("usb_detach_kernel_driver_np Error.(%s)\n",usb_strerror());
       }
}
if(usb_claim_interface(dh,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
       if(usb_detach_kernel_driver_np(dh,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
           printf("usb_claim_interface Error.\n");
           printf("usb_detach_kernel_driver_np Error.(%s)\n",usb_strerror());
       }
   }

if(usb_claim_interface(dh,dev->config->interface->altsetting->bInterfaceNumber)<0 ){
       printf("usb_claim_interface Error.(%s)\n",usb_strerror());
   }

USBの仕様に合わせて書いていく部分

アクセスするUSBデバイスの「bmRequestType」や「bRequest」、「wValue」、「wIndex」、「wLength」などとエンドポイントなどを調べておく必要がある。

メッセージ、コマンドを送る

それぞれの変数(bmRequestType, bRequest, wValue, wIndex,timeout)を宣言しておく必要がある。これらは上述の値を使う。
USB機器から帰ってくる応答は「msg(配列)」に格納される。ここでは返答は8バイトを想定している。

unsigned char msg[8];
int result=usb_control_msg(dh, bmRequestType, bRequest, wValue, wIndex, msg, sizeof(msg), timeout);
if(result<0){printf ("Control message error. (%s)\n", usb_strerror());}

resultの結果は本来「sizeof(msg)」と同じはず。

バルクデータを読む

「bytes」バイトだけバルクモードで読み込む。読み込んだデータは「readbuf(配列)」に格納される。
「end_point」は機器で指定されたもの。

result=usb_bulk_read(dh, end_point, readbuf, bytes, timeout);
if(result<0){printf ("bulk read error. (%s)\n", usb_strerror());}

resultの結果が負の場合エラーだけれど、本来resultの値は「bytes」と同じはずなのでエラートラップを下のように厳しくしてもいい。

result=usb_bulk_read(dh, end_point, readbuf, bytes, timeout);
if(result < bytes){printf ("bulk read error. (%s)\n", usb_strerror());}

デバイスを閉じる

最後に「usb_close」で閉じることを忘れない

usb_close(dh);

サンプル

簡単なサンプル。デバイスを見つけて開いて閉じるだけ。

その他、EZ-USB FX2用のサンプルを「EZ-USB FX2」に置いておく。

コンパイル

コンパイルするときは「-lusb」というオプションをつける。

gcc -lusb -o hoge hoge.c

上のサンプルなら

gcc -lusb -o test_libusb0 test_libusb0.c

リファレンス

Core

usb_init

初期化。一番初めに呼ぶ。

void usb_init(void);

usb_find_busses

全てのUSBバスを見つける。返す値は前回呼ばれたときのバスの数と今のバスの数の違い

int usb_find_busses(void);

usb_find_devices

つながっているUSBデバイスを探す。usb_find_bussesの後に呼ぶ必要がある。返す値は前回との違い

int usb_find_devices(void);

usb_get_busses

見つかったUSBバスのリストを返す

struct usb_bus *usb_get_busses(void);

Device operations

usb_open

USBデバイスを開く。いろいろな操作の前に開く必要がある。USBデバイスのハンドルを返す

usb_dev_handle *usb_open(struct *usb_device dev);

usb_close

USBデバイスを閉じる。いろいろな操作の後に閉める。成功すると0を返して失敗すると負の値を返す

int usb_close(usb_dev_handle *dev);

usb_set_configuration

デバイスの設定を行う。成功すると0を返して失敗すると負の値を返す

int usb_set_configuration(usb_dev_handle *dev, int configuration);

「configuration」にはUSBデバイスが指定している「bConfigurationValue」の値を入れる

usb_set_altinterface

現在使用中のデバイスの代替設定を行う。成功すると0を返して失敗すると負の値を返す

int usb_set_altinterface(usb_dev_handle *dev, int alternate);

「alternate」にはUSBデバイスで指定している「bAlternateSetting」の値を入れる

usb_clear_halt

エンドポイントをクリアする。成功すると0を返して失敗すると負の値を返す

int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);

「ep」はエンドポイント。「bEndpointAddress」の値を入れる

usb_reset

デバイスをリセット。成功すると0を返して失敗すると負の値を返す

int usb_reset(usb_dev_handle *dev);

これを使った後はまた初期化プロセスを行う必要があるみたい

usb_claim_interface

デバイスのインターフェースを要求。成功すると0を返して失敗すると負の値を返す

int usb_claim_interface(usb_dev_handle *dev, int interface);

「interface」にはUSBデバイスが指定している「bInterfaceNumber」をいれる
このインターフェースに関係した関数(「usb_set_altinterface」や「usb_bulk_write」)などの前に呼ぶ必要がある

usb_release_interface

前に要求されたインターフェースを開放。成功すると0を返して失敗すると負の値を返す

int usb_release_interface(usb_dev_handle *dev, int interface);

「interface」にはUSBデバイスが指定している「bInterfaceNumber」をいれる

Control Transfers

usb_control_msg

コントロールメッセージをデバイスに送る。成功すると読み書きしたバイト数を返し失敗すると負の値を返す

int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);

「bytes」に送るメッセージが入り、「size」はそのメッセージのバイト数。このサイズと成功した時に返される値は同じはず。
「requesttype」、「request」、「index」などにはUSBデバイスが指定している値が入る

usb_get_string

デバイスから文字列を受け取る。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す

int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);

「buflen」で指定した長さのデータを受け取る。「buflen」と成功した時に返される値は同じはず。
「index」と「langid」で決められたデータを受け取る。受け取ったデータは「buf」に入る。

usb_get_string_simple

int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);

usb_get_descriptor

int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);

usb_get_descriptor_by_endpoint

int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);

Bulk Transfers

usb_bulk_write

「ep」で指定したエンドポイントへ「bytes」(「size」サイズ)のバルクデータを書き込む。成功すると送ったデータのバイト数を返し失敗すると負の値を返す

int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

「size」と成功した時に返される値は同じはず。

usb_bulk_read

「ep」で指定したエンドポイントから「size」サイズのバルクデータを読み込み「bytes」に入れる。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す

int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

「size」と成功した時に返される値は同じはず。

Interrupt Transfers

usb_interrupt_write

「ep」で指定した割り込みエンドポイントへ「bytes」(「size」サイズ)のバルクデータを書き込む。成功すると送ったデータのバイト数を返し失敗すると負の値を返す

int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

「size」と成功した時に返される値は同じはず。

usb_interrupt_read

「ep」で指定した割り込みエンドポイントから「size」サイズのバルクデータを読み込み「bytes」に入れる。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す

int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

「size」と成功した時に返される値は同じはず。

Non Portable

usb_get_driver_np

int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, int namelen);

usb_detach_kernel_driver_np

int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);

参考リンク


広告

添付ファイル: filetest_libusb0.c 9407件 [詳細]

リロード   差分   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Thu, 05 Jan 2012 17:12:07 JST (2636d)