広告
「libusb
」は簡単にUSB機器にアクセスできるように作られたC言語用ライブラリ。
カーネルの変更や専用のドライバを必要としないので開発は楽。
Windows版
も存在する
--目次--
準備
- 「libusb
」がインストールされていなかったらインストールする。
- さまざまなディストリビューションにパッケージが用意されているので、インストールは簡単。
- アクセスするUSB機器のベンダーIDとプロダクトIDを調べる。機器の説明書や仕様書に載っている。
- 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
初期化。一番初めに呼ぶ。
void usb_init(void);
全てのUSBバスを見つける。返す値は前回呼ばれたときのバスの数と今のバスの数の違い
int usb_find_busses(void);
つながっているUSBデバイスを探す。usb_find_bussesの後に呼ぶ必要がある。返す値は前回との違い
int usb_find_devices(void);
見つかったUSBバスのリストを返す
struct usb_bus *usb_get_busses(void);
USBデバイスを開く。いろいろな操作の前に開く必要がある。USBデバイスのハンドルを返す
usb_dev_handle *usb_open(struct *usb_device dev);
USBデバイスを閉じる。いろいろな操作の後に閉める。成功すると0を返して失敗すると負の値を返す
int usb_close(usb_dev_handle *dev);
デバイスの設定を行う。成功すると0を返して失敗すると負の値を返す
int usb_set_configuration(usb_dev_handle *dev, int configuration);
「configuration」にはUSBデバイスが指定している「bConfigurationValue」の値を入れる
現在使用中のデバイスの代替設定を行う。成功すると0を返して失敗すると負の値を返す
int usb_set_altinterface(usb_dev_handle *dev, int alternate);
「alternate」にはUSBデバイスで指定している「bAlternateSetting」の値を入れる
エンドポイントをクリアする。成功すると0を返して失敗すると負の値を返す
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
「ep」はエンドポイント。「bEndpointAddress」の値を入れる
デバイスをリセット。成功すると0を返して失敗すると負の値を返す
int usb_reset(usb_dev_handle *dev);
これを使った後はまた初期化プロセスを行う必要があるみたい
デバイスのインターフェースを要求。成功すると0を返して失敗すると負の値を返す
int usb_claim_interface(usb_dev_handle *dev, int interface);
「interface」にはUSBデバイスが指定している「bInterfaceNumber」をいれる
このインターフェースに関係した関数(「usb_set_altinterface」や「usb_bulk_write」)などの前に呼ぶ必要がある
前に要求されたインターフェースを開放。成功すると0を返して失敗すると負の値を返す
int usb_release_interface(usb_dev_handle *dev, int interface);
「interface」にはUSBデバイスが指定している「bInterfaceNumber」をいれる
コントロールメッセージをデバイスに送る。成功すると読み書きしたバイト数を返し失敗すると負の値を返す
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デバイスが指定している値が入る
デバイスから文字列を受け取る。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);
「buflen」で指定した長さのデータを受け取る。「buflen」と成功した時に返される値は同じはず。
「index」と「langid」で決められたデータを受け取る。受け取ったデータは「buf」に入る。
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);
int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);
int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);
「ep」で指定したエンドポイントへ「bytes」(「size」サイズ)のバルクデータを書き込む。成功すると送ったデータのバイト数を返し失敗すると負の値を返す
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
「size」と成功した時に返される値は同じはず。
「ep」で指定したエンドポイントから「size」サイズのバルクデータを読み込み「bytes」に入れる。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
「size」と成功した時に返される値は同じはず。
「ep」で指定した割り込みエンドポイントへ「bytes」(「size」サイズ)のバルクデータを書き込む。成功すると送ったデータのバイト数を返し失敗すると負の値を返す
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
「size」と成功した時に返される値は同じはず。
「ep」で指定した割り込みエンドポイントから「size」サイズのバルクデータを読み込み「bytes」に入れる。成功すると受け取ったデータのバイト数を返し失敗すると負の値を返す
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
「size」と成功した時に返される値は同じはず。
int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, int namelen);
int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);
参考リンク
広告