项目地址:点击打开
使用java开发的好处就是跨平台,基本上java的开发的程序在linux、mac、MS上都可以运行,对应这java的那句经典名言:一次编写,到处运行。这个项目里面有两种包选择,一个是low-level(libus)一个是high-level(javax-usb),相关的优缺点在官方网站上已经说明了,我这里就不翻译了,不过前者好像基于libusb已经好久不更新了,所以还是选择后者。
配置:你需要在你包的根目录下新建一个名为:javax.usb.properties的文件,里面的内容是这样的:
javax.usb.services = org.usb4java.javax.Services
查找usb设备,其实通过usb通信流程大体上都是一致,之前我做过android与arduino通过usb通信,然后java通信走了一遍之后发现是一样的。USB 设备在一棵树上进行管理。这树的根是所有物理根集线器连接到一个虚拟的 USB集线器。更多的集线器可以连接到这些根集线器和任何集线器可以有大量的连接的 USB设备。
通常,您需要在使用它之前搜索特定设备,下面的是一个例子如何扫描与一个特定的供应商和产品 id 的第一个设备的设备:
public UsbDevice findDevice(UsbHub hub, short vendorId, short productId) { for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices()) { UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor(); if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device; if (device.isUsbHub()) { device = findDevice((UsbHub) device, vendorId, productId); if (device != null) return device; } } return null; }
接口
当你想要与一个接口或者这个接口的端点进行通信时,那么你在使用它之前必须要claim它,并且当你结束时你必须释放它。比如:下面的代码:
UsbConfiguration configuration = device.getActiveUsbConfiguration(); UsbInterface iface = configuration.getUsbInterface((byte) 1); iface.claim(); try { ... Communicate with the interface or endpoints ... } finally { iface.release(); }
可能出现的一种情况是你想要通信的接口已经被内核驱动使用,在这种情况下你可能需要通过传递一个接口策略到claim方法以此尝试强制claim:
iface.claim(new UsbInterfacePolicy() { @Override public boolean forceClaim(UsbInterface usbInterface) { return true; } });
需要注意的是,接口策略只是为了实现基础USB的一个提示.接口策略在MS-Windows上将被忽略,因为libusb在windows上不支持分派驱动。
同步 I/O
这个example发送8个字节到端点0x03:
UsbEndpoint endpoint = iface.getUsbEndpoint(0x03); UsbPipe pipe = endpoint.getUsbPipe(); pipe.open(); try { int sent = pipe.syncSubmit(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }); System.out.println(sent + " bytes sent"); } finally { pipe.close(); }
这个example是从端点0x83读取8个字节:
UsbEndpoint endpoint = iface.getUsbEndpoint((byte) 0x83); UsbPipe pipe = endpoint.getUsbPipe(); pipe.open(); try {