我正在编写软件以在平板电脑之间进行通信(摩托罗拉Xoom与Android版本4.0.3和内核版本2.6.39.4)以及使用USB Host API提供的外围设备通过Android。我只使用两种类型的通信:
controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)
控制转移工作正常,但我有批量转移的问题。我只能使用32768作为bulkTransfer函数的缓冲区大小。不可能使用更少或更多。我知道由于缓冲管的限制(大小:32769字节),我不能使用更多。
此外围设备流式传输bulkTranfer函数无法正确读取的数据。我想有些数据会丢失。
基于此,我对该问题的解释是由于write(2)函数产生的阻塞标志,一些数据没有写入管道(缓冲区)。我对么?如果这是真的,我可以改变管道缓冲区。
fcntl(fd, F_SETPIPE_SZ, size)
但我怎样才能找到fd
(文件描述符)
USB管? ulimit -p SIZE
,但我的内核的参数p
不是用于管道而是用于处理。有没有人遇到同样的问题,任何解决方案?
答案 0 :(得分:2)
你应该得到一个USB数据分析仪,我正在使用这个:http://www.ellisys.com/products/usbex200/index.php
当我做同样的事情时,使用这样的东西真的帮助了我,我发现你必须做某种类型的while循环。
对于我的设备,我有64个字节的数据包进入我,数据包将是两个控制字节,62个数据,所以对于我的传输,我必须做类似的事情
StringBuilder sb = new StringBuilder();
while(bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) > 2){
for(int i = 2; i < buffer.length(); i++){
sb.append((char) buffer[i]);
}
}
很长一段时间这些线对我有用,我有完全相同的问题,这就是我修复它的方法。如果您需要,我会提供更多信息。只是评论:)。我知道这对我来说真的很令人沮丧。我使用Acer Iconia A500与Android 4.0.3 btw
答案 1 :(得分:1)
根据同样的.pdf gfour发布,我在那里找到了这一段:
“数据包的大小将影响性能,并且取决于数据速率。对于非常高的速度,需要最大的数据包大小。对于以115200波特传输音频数据的”实时“应用程序,例如,最小的数据包是可取的,否则设备将一次保持4k的数据。如果USB请求数量太大而数据速率太低(相对),这可能会产生'不稳定'的数据传输效果。“
我遇到了类似于带有FTDI串行设备的SmartLemon的情况,所以我最近一直在寻找缓解它的方法。这将要求我在以前使用库时从头开始编写自己的函数。
然而,在您的情况下,您可以尝试使用bulkTransfer的最低缓冲区大小而不是拍摄最大的缓冲区大小。你可能已经尝试过了,但也许没有。我看到你说32768是唯一的尺寸,但也许你只是意味着最大。它似乎很奇怪它只允许一个特定的大小。
答案 2 :(得分:1)
Android SDK的 UsbEndpoint 对象提供了 getMaxPacketSize()方法,可让您检查适合您设备的内容。通常,对于USB&#39;全速&#39;,最大允许数据包大小为64字节。设备和512用于&#39;高速&#39;设备 - 远不及你尝试的32,768。您是否可能将基础USB数据包大小与某些更高级别的协议混淆?
答案 3 :(得分:0)
根据AN232B-04_DataLatencyFlow.pdf,高数据率需要流量控制:
强烈建议使用流量控制,因为它是 无法确保始终安排FTDI驱动程序。
您是否尝试过使用其中一个流量控制选项(RTS / CTS,DTR / DSR,XON / XOFF)来同步数据?
答案 4 :(得分:-1)
您可以尝试批量转移问题
byte[] buffer = new byte[4096];
StringBuilder strIN = new StringBuilder();
if (conn.bulkTransfer(epIN, buffer, 4096, 500) >= 0) {
for (int i = 2; i < 4096; i++) {
if (buffer[i] != 0) {
strIN.append((char) buffer[i]);
textReceiveDataInfo.append(strIN + "\n");
} else {
l(strIN);
break;
}
}
}