#freeze
[[FrontPage]]

2008/10/14 からのアクセス回数 &counter;

#contents

[[avr/USB接続]]でlibusbを使って自作のUSBデバイスにアクセスすることができるようになりました。
次は、javaからこのUSBデバイスを操作してみます。

** LibusbJava [#c29ea8e8]
まず、libusbのjavaラッパーが必要です。
世の中には、自分がやりたいと思うことをすでにやっている人がいますから、自分で最初から作る前に
#pre{{
libusb java
}}
でグーグル検索すると
- [[Java libusb / libusb-win32 wrapper>http://libusbjava.sourceforge.net/wp/]]

を見つけることができました。

Windowsの人は、
- [[installation>http://libusbjava.sourceforge.net/wp/?page_id=8]]
を参考してください。

** ソースからのコンパイル [#we572fde]
私はMacOSXなので、SVNからソースをダウンロードしてコンパイルすることにしました。

*** チェックアウト [#y9a2aebc]
Eclipseを使って、

[[SVN>https://libusbjava.svn.sourceforge.net/svnroot/libusbjava]]から
- trunk/java
- trunk/libusbJava

をチェックアウトします。

*** MacOSX用のダイナミックライブラリの作成 [#ddb204b7]
次に、LibusbJavaを使ってMacOSX用のダイナミックライブラリを作成します。

LibusbJavaプロジェクトの
build.xmlの22行に以下の1行を追加してください。
#pre{{
	<property name="version.mac" value="${version.major}.${version.minor}.${version.micro}" />
}}

次にbuild.xmlを選択し、右クリックでRun As->Ant build...を選択します。
ターゲットして、Macを選択するとLibusbJava.jnilibが作成されます。

*** ch.ntb.usb-0.5.7.jarの作成 [#tb312e58]
同様に、ch.ntb.usbプロジェクトでbuild.xmlを使ってjarファイルを作成します。


** テストプロジェクトの作成 [#m3b6848b]
Eclipseで新規プロジェクトで、

- UsbTiny45プロジェクトを作成します。
-ここにLibusbJava.jnilib、ch.ntb.usb-0.5.7.jarをコピーします。
- ch.ntb.usb-0.5.7.jarをビルドパスに追加します。

*** テストプログラム [#t12c5b66]
テストプログラムUSBTiny45.javaを作成します。

- C版同じように、usbOpenDeviceは以下のようになります。
#pre{{
	static long usbOpenDevice(short idvendor, short idproduct) throws USBException {
		Usb_Device	dev = null;
		Usb_Bus		bus = USB.getBus();
		long		usbHandle = 0L;
		while (bus != null) {
			dev = bus.getDevices();
			while (dev != null) {	
				usbHandle = LibusbJava.usb_open(dev);
				if (usbHandle != 0) {
					Usb_Device_Descriptor devDesc = dev.getDescriptor();
					String retp = LibusbJava.usb_get_string_simple(usbHandle, 
                                                                (int)devDesc.getIProduct());
					String retm = LibusbJava.usb_get_string_simple(usbHandle,
                                                                (int)devDesc.getIManufacturer());
					if (retp != null && retm != null) {
						if (devDesc.getIdVendor() == idvendor
								&& devDesc.getIdProduct() == idproduct) {
							return usbHandle;
						}
					}
				}
				dev = dev.getNext();
			}
			bus = bus.getNext();
		}
		LibusbJava.usb_close(usbHandle);
		return 0L;		
	}
}}

- 実行部分も
#pre{{
	static private void testUsbOpenDevice() throws Exception {
		byte[]	buffer = new byte[2312];
		int		i=3, j=4, k=5, l=6, m=7, n=8, o=9;
		int		ret;

		long devHandle = usbOpenDevice(vendorId, productId);
		if (devHandle == 0) {
			System.err.println("usbOpenDevice failed\n");
			return;
		}
		ret = LibusbJava.usb_control_msg(devHandle,
				USB.REQ_TYPE_TYPE_VENDOR|USB.REQ_TYPE_RECIP_DEVICE
				|USB_ENDPOINT_IN, 
				i, j+256*k, l+256*m, buffer, n+256*o, 5000);
		System.out.format("ret=%d \n", ret);
		for (int p=0; p < ret; p++) {
			System.out.format("buffer[%d]=%d \n", p, buffer[p]);
		}
		LibusbJava.usb_close(devHandle);		
	}
}}
とします。

** 動作確認 [#zc3d669d]
これでよしとmain関数を実行したのですが、うまく動きません。

- libusbJava版は、ハブに接続したUSBデバイスをうまく認識しない。

ことが分かりました。

USBデバイスが認識されているかは、ch.ntb.usb-0.5.7.jarのUsbViewのmainメソッドを実行すると分かります。


めでたく、実行結果がCと同じく
#pre{{
ret=7 
buffer[0]=9 
buffer[1]=3 
buffer[2]=4 
buffer[3]=5 
buffer[4]=6 
buffer[5]=7 
buffer[6]=8 
}}
になりました。

** ch.ntb.usbの変更 [#a5d7fdf2]
Device.java#initDeviceの114行目の
#pre{{
					updateMaxPacketSize(device);
}}

をdevDesc.getAltinterface()が-1の時には、コールしないように修正すれば、

テストプログラムは、以下のように簡単になります。

#pre{{
	static private void testDeviceAndUSB() throws Exception {
		byte[]	buffer = new byte[2312];
		int		i=3, j=4, k=5, l=6, m=7, n=8, o=9;
		int		ret;

		Device device = USB.getDevice(vendorId, productId);
		if (device == null) {
			System.err.println("usbOpenDevice failed\n");
			return;
		}
		device.open(1, 0, -1);
		ret = device.controlMsg(
				USB.REQ_TYPE_TYPE_VENDOR|USB.REQ_TYPE_RECIP_DEVICE
				|USB_ENDPOINT_IN, 
				i, j+256*k, l+256*m, buffer, n+256*o, 5000, false);
		System.out.format("ret=%d \n", ret);
		for (int p=0; p < ret; p++) {
			System.out.format("buffer[%d]=%d \n", p, buffer[p]);
		}
		device.close();
		
	}
}}

** ファイル [#fb2ac0cb]
作成したUSBTiny45.javaは以下からダウンロードできます。

#ref(USBTiny45.java);

** Snow LeopardでLibusbJava.jnilibを作る方法 [#v380fe77]
2代目のMacMiniのOSをSonw Leopardにアップグレードしたら、Tigerで作ったLibusbJava.jnilibが動作しなくなってしまいました。

仕方なく、もう一度antを実行したのですが、ダメです。ここでは、試行錯誤の結果どうにかLibusbJava.jnilibができたので、その方法をメモしておきます。

*** 最新のソースをチェックアウト [#l752c2fd]
どうせなら、最新のソースにアップすることにしました。

チェックアウトは、以下のように行います。
#pre{{
$ svn co https://libusbjava.svn.sourceforge.net/svnroot/libusbjava/trunk/LibusbJava/
}}

*** libusbもアップグレード [#m962f33d]
OSの変更でMacPortのlibusbを作り直しました。

LibusbJavaのページには、0.1の古いバージョンを使うとあるので、llibusb-compatもインストールします。
また、libusb-compatには、libusbppが含まれないのでlibusb-legacyもインストールします。
#pre{{
$ sudo port install libusb
$ sudo port install libusb-compat
$ sudo port install libusb-legacy
}}

次に、libusbJavaが/usr/local/lib/libusb.dylib、/usr/local/lib/libusbpp.dylibを参照しているので、
シンボリックリンクを作ります。
#pre{{
$ cd /usr/local/lib
$ sudo ln -s /opt/local/lib/libusb-0.1.4.dylib ./libusb.dylib
$ sudo ln -s /opt/local/lib/libusb-legacy/libusbpp-legacy.dylib ./libusbpp.dylib
}}

*** コンパイル [#n541013a]
ソースファイルをチェックアウトした場所に戻って、コンパイルをします。

#pre{{
$ ant mac
途中省略
     [exec]  /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic 
	-dylib -dylib_current_version 0.2.4.0 -arch x86_64 -macosx_version_min 10.6.6 
	-weak_reference_mismatches non-weak -o libusbJava.jnilib 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64 
	-L/usr/lib/i686-apple-darwin10/4.2.1 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 
	-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. 		
	/var/folders/Xo/XoxQsiGT2RWIck+BYuxhKU+++TI/-Tmp-//cc725VBz.o 
	-lstdc++ /usr/local/lib/libusb.dylib /usr/local/lib/libusbpp.dylib -lSystem -lgcc -lSystem
     [exec] ld: malformed version number: 0.2.4.0
     [exec] collect2: ld returned 1 exit status
     [exec] Result: 1
}}
とcollect2の実行でldがmalformed versionエラーを出力します。

原因は、collect2の引数の
#pre{{
-dylib_current_version 0.2.4.0
}}
オプションのバージョンにあるようで、これを除くとエラーはでません。

そこで、build.xmlの90行目の
#pre{{
                        <arg line="-current_version ${version}" />
}}
を削除して、
#pre{{
$ ant mac
}}
を実行すると、無事Snow Leopardで動くLibusbJava.jnilibができます。

*** Snow Leopard版のLibusbJava.jnilib [#raa4c85b]
念のため、作成したLibusbJava.jnilibを以下に置いておきます。
- &ref(libusbJava.jnilib);

** コメント [#oac99957]
この記事は、

#vote(おもしろかった[9],そうでもない[0],わかりずらい[0])
#vote(おもしろかった[10],そうでもない[0],わかりずらい[1])

皆様のご意見、ご希望をお待ちしております。
- Snow LeopardでLibusbJava?.jnilibを作る方法を追加しました -- [[竹本 浩]] &new{2011-02-05 (土) 22:14:54};
- usb4javaの記事を書いてください。宜しくね -- [[重松]] &new{2015-09-14 (月) 11:16:56};

#comment_kcaptcha

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc