13

我正在编写软件以在平板电脑(Android 版本 4.0.3 和内核版本 2.6.39.4 的摩托罗拉 Xoom)和使用 Android 提供的 USB Host API 的外围设备之间进行通信。我只使用两种类型的通信:

  • 控制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 函数未正确读取的数据。我想有些数据丢失了。

我发现这一点:在 Linux 中,如果一个进程试图从一个空管道(缓冲区)中读取,那么 read(2) 将阻塞,直到数据可用。如果一个进程尝试写入一个完整的管道,那么 write(2) 会阻塞,直到从管道中读取了足够的数据以允许写入完成。

基于此,我对问题的解释是,由于 write(2) 函数产生的阻塞标志,一些数据没有写入管道(缓冲区)。我对么?如果这是真的,我可以更改管道缓冲区。

  1. 我对这个问题的第一个解决方案是更大的缓冲区。对于内核> = 2.6.35,您可以更改管道的大小,fcntl(fd, F_SETPIPE_SZ, size)但如何找到fdUSB管道的(文件描述符)?
  2. 第二种选择是使用ulimit -p SIZE,但p我的内核的参数不是管道而是进程。

有没有人遇到过同样的问题,有解决办法吗?

4

5 回答 5

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]);
    }
}

这些行很长的东西对我很有用,我遇到了完全相同的问题,这就是我修复它的方法。如果您需要,我有更多信息。只是评论:)。我知道这对我来说真的很令人沮丧。我正在使用带有 Android 4.0.3 的 Acer Iconia A500


传输大量数据 USB

传输数据 USB

于 2012-06-12T22:01:37.983 回答
1

Android SDK 的UsbEndpoint对象提供了一个getMaxPacketSize()方法,允许您检查适合您设备的内容。通常,USB“全速”设备的最大允许数据包大小为 64 字节,“高速”设备为 512 字节 - 远小于您尝试的 32,768 个字节。您是否可能将底层 USB 数据包大小与某些更高级别协议的大小混淆了?

于 2014-12-31T06:30:58.273 回答
1

根据相同的 .pdf gfour 发布,我在那里找到了这段:

“数据包的大小会影响性能并取决于数据速率。对于非常高的速度,需要最大的数据包大小。例如,对于以 115200 波特传输音频数据的“实时”应用程序,最小的可能的数据包是可取的,否则设备将一次保存 4k 数据。如果 USB 请求大小太大且数据速率太低(相对),这可能会产生“急速”数据传输的效果。”

我遇到了类似于带有 FTDI 串行设备的 SmartLemon 的情况,所以我最近一直在寻找缓解它的方法。这将需要我从头开始编写自己的函数,而之前我使用的是库。

但是,在您的情况下,您似乎可以尝试使用 bulkTransfer 的最低缓冲区大小,而不是使用最大的缓冲区。您可能已经尝试过,但可能还没有。我看到你说 32768 是唯一的大小,但也许你只是指最大值。它只允许一种特定的尺寸似乎很奇怪。

于 2012-11-27T21:36:04.180 回答
0

根据AN232B-04_DataLatencyFlow.pdf,高数据速率需要流量控制:

强烈建议使用流控制,因为无法确保始终调度 FTDI 驱动程序。

您是否尝试过使用流控制选项之一(RTS/CTS、DTR/DSR、XON/XOFF)来同步您的数据?

于 2012-06-14T15:32:08.177 回答
0

你可以试试这个批量转移问题

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;
                    }
                }

            }
于 2013-09-11T06:43:56.083 回答