我有一个带有按钮的 USB 设备。我想要一个 android 应用程序来捕捉按钮的信号。我找到了按钮的接口和端点编号。它似乎在 Galaxy S3 和 Galaxy Note 上表现一般。但后来,我发现它在其他手机上有延迟。
我能够在大约 10% 的时间内收到即时回复;通常会有 2 秒的延迟,在某些情况下会丢失整个响应。
虽然我无法弄清楚确切的原因,但我意识到响应延迟的手机是内核版本为 3.4 或更高版本的手机。
这是我最初使用的代码。
if(mConnection != null){
mConnection.claimInterface(mInterfaces.get(0), true);
final UsbEndpoint endpoint = mInterfaces.get(0).getEndpoint(0);
Thread getSignalThread = new Thread(new Runnable() {
@Override
public synchronized void run() {
byte[] buffer = new byte[8];
final ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
while(mConnection!=null){
int len = mConnection.bulkTransfer(endpoint, buffer, buffer.length, 0);
if( len>=0 ){
// do my own code
}
}
}
});
getSignalThread.setPriority(Thread.MAX_PRIORITY);
getSignalThread.start();
}
编辑超时
当超时设置为 50 毫秒时,我大部分时间都无法收到响应。当超时为 500 毫秒时,我最初能够得到一些延迟响应;但是,在使用此设置多次尝试后,我失去了所有响应。
使用 UsbRequest
除了使用批量传输方法外,我还尝试使用 UsbRequest,下面是我使用的代码。
@Override
public synchronized void run() {
byte[] buffer = new byte[8];
final ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
UsbRequest inRequest = new UsbRequest();
inRequest.initialize(mConnection, endpoint);
while(mConnection!=null){
inRequest.queue( byteBuffer , buffer.length);
if( mConnection.requestWait() == inRequest ){
// do my own code
}
}
}
但是,即使在使用 UsbRequest 之后,也会发生同样的延迟。
使用 libusb
我还尝试使用名为 libusb 的开源库中的libusb_interrupt_transfer 。然而,这也产生了与我使用 UsbDeviceConnection 时相同类型的延迟。
unsigned char data_bt[8] = { 0, };
uint32_t out[2];
int transfered = 0;
while (devh_usb != NULL) {
libusb_interrupt_transfer(devh_usb, 0x83, data_bt, 8, &transfered, 0);
memcpy(out, data_bt, 8);
if (out[0] == PUSH) {
LOGI("button pushed!!!");
memset(data_bt, 0, 8);
//(env)->CallVoidMethod( thiz, mid);
}
}
在查看了libusb_interrupt_transfer处理libusb的部分之后,我能够弄清楚interrupt_transfer的一般步骤:1.创建一个interrupt类型的传输对象2.创建一个指向传输对象的urb对象3.提交urb对象到设备的 fd 4. 通过 urb 对象检测 fd 对象的任何变化 5. 通过 ioctl 读取 urb
步骤 3、4、5 是有关文件 i/o 的步骤。我发现在第 4 步,程序会等待按钮按下,然后再进行下一步。
因此我尝试将 poll 更改为 epoll 以检查 poll 函数是否导致延迟;不幸的是,没有任何改变。
我还尝试将 poll 函数的超时设置为 500ms 并使其始终通过 ioctl 获取 fd 的值,但仅发现在按下按钮后 2~3 秒该值发生了变化。
所以总而言之,我觉得按下按钮后更新fd值的过程有延迟。如果有人可以帮助我解决这个问题,请告诉我。谢谢你。
谢谢阅读