Android USB Host API:批量传输缓冲区大小

时间:2012-06-04 22:48:01

标签: android usb host

我正在编写软件以在平板电脑之间进行通信(摩托罗拉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函数无法正确读取的数据。我想有些数据会丢失。

我找到了这个:In Linux If a process attempts to read from an empty pipe (buffer), then read(2) will block until data is available. If a process attempts to write to a full pipe , then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete.

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

  1. 我对此问题的第一个解决方案是更大的缓冲区。 For kernel >= 2.6.35, you can change the size of a pipe with fcntl(fd, F_SETPIPE_SZ, size)但我怎样才能找到fd(文件描述符) USB管?
  2. 第二个选项是使用ulimit -p SIZE,但我的内核的参数p不是用于管道而是用于处理。
  3. 有没有人遇到同样的问题,任何解决方案?

5 个答案:

答案 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


Transferring larger amounts of data USB

Transferring data USB

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

            }