Android USB主机:中断不立即响应

时间:2015-12-15 08:13:22

标签: android libusb usb-otg

我有一个带按钮的USB设备。 我想要一个Android应用程序来捕获按钮的信号。 我找到了按钮的界面和端点号。 它似乎通常在星系S3和星系音符执行。 但后来,我发现它在其他手机上有延迟。

我能够在大约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

除了使用bulktransfer方法,我还尝试使用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.制作类型中断的传输对象 2.创建一个指向传输对象的urb对象 3.将urb对象提交给设备的fd 4.通过urb对象检测fd对象中的任何更改 5.通过ioctl阅读urb

步骤3,4,5是关于文件i / o的步骤。 我能够发现,在第4步,程序在进入下一步之前等待按下按钮。

因此,我尝试将轮询更改为epoll,以检查轮询功能是否导致延迟;遗憾的是没有任何改变。

我还尝试将poll函数的超时设置为500ms,并使其始终通过ioctl获取fd的值,但只发现按下按钮后值改变了2~3秒。

总而言之,我觉得按下按钮后更新fd值的过程有延迟。如果有人可以帮我解决这个问题,请告诉我。谢谢。

感谢您阅读

0 个答案:

没有答案