我有Android设备和Windows驱动程序。 我必须在配件模式下使用我自己的二进制协议进行通信。 是否可以在不编写自定义USB驱动程序的情况下将数据发送到此设备?
答案 0 :(得分:1)
USB是一种复杂的协议,因为它是'通用' ,可以处理各种设备(大容量存储,相机......)。因此,在您的Android设备上必须实现一个基本的USB结构,以使用标准库,如 libusb 或类似的东西。 您可以认为是这种情况,因为在大多数情况下,android在具有USB端口的处理器上使用。
见http://www.beyondlogic.org/usbnutshell/usb1.shtml。
您可以使用libusb -v
然后,如果您知道Android设备上的USB结构是什么样的,您可以使用 libusb 或其他库将数据写入usb结构中的特定端点,例如: libusb_bulk_transfer()
,libusb_control_transfer()
http://libusb.sourceforge.net/api-1.0/io.html
如果你想在java中编程你可以使用usb4java但是这有点不稳定http://usb4java.org/quickstart/libusb.html
通用USB结构是设备 - > (配置) - >界面 - >端点强>
因此,将数据写入端点的方法是:
libusb_init(NULL);
libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);
libusb_claim_interface(devh, 0);
libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT), data,
4, &p, 0); //example
... release interface...
...
libusb_close(devh);
libusb_exit(NULL);
以下是从http://www.dreamincode.net/forums/topic/148707-introduction-to-using-libusb-10/
复制的C ++示例#include <iostream>
#include <libusb.h>
using namespace std;
int main() {
libusb_device **devs; //pointer to pointer of device, used to
retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we
just declared
if(r < 0) {
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in
the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
cout<<"Get Device Error"<<endl; //there was an error
return 1;
}
cout<<cnt<<" Devices in list."<<endl;
dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424);
//these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
cout<<"Cannot open device"<<endl;
else
cout<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices
in it
unsigned char *data = new unsigned char[4]; //data to write
data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if
kernel driver is attached
cout<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
cout<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the
first) of device (mine had jsut 1)
if(r < 0) {
cout<<"Cannot Claim Interface"<<endl;
return 1;
}
cout<<"Claimed Interface"<<endl;
cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to
write : abcd
cout<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data,
4, &actual, 0); //my device's out endpoint was 2, found with trial-
the device had 2 endpoints: 2 and 129
if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
cout<<"Writing Successful!"<<endl;
else
cout<<"Write Error"<<endl;
r = libusb_release_interface(dev_handle, 0); //release the claimed
interface
if(r!=0) {
cout<<"Cannot Release Interface"<<endl;
return 1;
}
cout<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
因此,当您的设备运行Android时,它具有USB结构/功能。要调查设备的USB功能(设备类,如大容量存储,RNDIS,... ),请使用libusb -v
并查看上面的代码,将自定义数据写入其中一个端点上设备。