我正在尝试与使用中断传输进行通信的 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/