Android USB主机中断传输: how to TX and RX at any time

标签 android

我正在尝试与使用中断传输进行通信的 USB 设备进行通信。 它不是轮询设备,任何一方都可以随时发送。我找到的所有示例似乎都是轮询响应,您先发送数据,等待发送完成,然后等待响应,处理它,然后返回再次发送数据。

我的代码是根据我在 stackoverflow 上找到的以下代码建模的(我展示了我基于它的原始代码,因为我自己的代码有更多的内容并且不太紧凑)

  boolean retval = request.queue(buffer, 1); 
    if (mConnection.requestWait() == request) { 
         // wait for confirmation (request was sent)
         UsbRequest inRequest = new UsbRequest(); 
         // URB for the incoming data
         inRequest.initialize(mConnection, mEndpointIn); 
         // the direction is dictated by this initialisation to the incoming endpoint.
         if(inRequest.queue(buffer, bufferMaxLength) == true){
              mConnection.requestWait(); 
              // wait for this request to be completed
              // at this point buffer contains the data received
         }
    }

第二个 requestWait() 会阻塞,直到有东西到达,所以在我收到东西之前我不能做另一个 TX 操作!我错过了什么?

最佳答案

你说:“第二个 requestWait() 会阻塞直到有东西到达,所以在我收到东西之前我不能做另一个 TX 操作”

我也根据您展示的示例编写了自己的代码,我想我理解您感到困惑的地方:第二个 requestWait() 将返回任何 USB 操作,而不仅仅是那个在它之前。 (来自 Android API 文档“请注意,这可能会返回在多个 UsbEndpoints 上排队的请求”)

因此,如果您在等待时将发送请求排队,您的“接收等待请求”将返回,但对于发送端点。您应该始终检查 waitRequest 结果的端点,或将其与初始请求本身进行比较。如果它与 inRequest 匹配,那么它实际上是您阻止的接收操作。如果不匹配,将它与您的发送请求进行比较(或者在我下面的示例代码中,我只是假设它是一个发送响应并忽略它)

您需要对来自不同方法或线程的发送和接收请求进行排队,而不是像您提供的代码所隐含的那样在同一个循环中。

这是我自己项目中的代码(请注意,我的应用程序遇到了堆损坏,因此下面的代码可能并不完美,但它确实允许我在接收操作挂起时发送)

这是我的接收循环,您会看到与您的代码的相似之处:

    while(mUsbDevice != null ) {

        if (inRequest.queue(buffer, BUFFER_SIZE) == true) {
            // (mUsbConnection.requestWait() is blocking
            if (mUsbConnection.requestWait() == inRequest){

                // this is an actual receive
                // do receive processing here (send to conusmer)

            } else{
                Log.d(TAG, "mConnection.requestWait() returned for a different request (likely a send operation)");
            }
        } else {
            Log.e(TAG, "failed to queue USB request");
        }
        buffer.clear();
    }

我从另一个线程执行发送,该线程使用消息对传入的发送请求进行排队:

        mHandler = new Handler() {
            public void handleMessage(Message msg) {                    
                if (msg.what == 1) { // 1 means send a 64 bytes array in msg.obj
                    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
                    final byte[] array = (byte[]) msg.obj;                      
                    buffer.clear();
                    buffer.put( array );
                    UsbRequest outRequest = new UsbRequest();
                    outRequest.initialize(mUsbConnection, mUsbEndpointOut);
                    outRequest.queue(buffer, BUFFER_SIZE);
                    Log.d(L.TAG, "Queueing request:"+outRequest);
                    // don't do a mConnection.requestWait() here, ReceiveThread is already listening 
                } else if (msg.what == 2) { // 2 means exit
                    Log.d(L.TAG,  "SenderThread::handleMessage(): terminate");
                    Looper.myLooper().quit();
                } else {
                    Log.e(L.TAG, "SenderThread::handleMessage(): unknow message type: " + msg.what);
                }
            }
        };

关于Android USB主机中断传输: how to TX and RX at any time,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21974562/

相关文章:

android - Google 登录无法正常工作

android - 发送短信时空指针异常,Parcel.ReadException?

java - 如何用Java制作一个Android倒计时器?

java - 在 android 中使用 intent 发送短信后不显示 toast

android - Webview "mailto:"链接和 "tel:"链接使用 Intent.ACTION_VIEW 工作,但是我如何添加唯一的主题即 "mailto:"链接

java - Intent 为空

android - list 中的 "category"是什么意思?

android - 几次尝试后无法看到 Facebook 权限页面

android - 使用 RoboSpice 有没有办法从异常中获取 HTTP 错误代码?

java - Android 基于表单的布局