2

我有一个带有按钮的 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值的过程有延迟。如果有人可以帮助我解决这个问题,请告诉我。谢谢你。

谢谢阅读

4

0 回答 0