2012-02-02 289 views
35

我试图从基于FTDI 2232H芯片的自定义设备接收数据。Android USB主机 - bulkTransfer()丢失数据

我正在使用一个简单的异步FIFO模式,并且传入数据速率是3.2MB /秒。

一切工作完美与我的电脑上的测试代码,但我遇到问题,我的东芝舒马上收到数据。

TDI的Android驱动失败,所以我使用Java编码。

我可以完美地获得95%以上的数据,但每过一段时间,数据就会“溅”出来,我会得到相同的4-5K数据的部分两到三次,然后返回到良好的数据。

我对Thrive或Android的速度并不太快,因为我之前的数据以双倍(6.4MB /秒)的速度进入,而且它的速度也达到了95%。 (所以它应该没有问题,一半的速度。)

这似乎是在Android中发生的缓冲(或双缓冲)中的某种错误。 (它不是FTDI 2232H内的缓冲区,因为重复的数据大于芯片的4K内部缓冲区。)

设置代码很简单,而且它的工作几乎完美。

在数据抓取时的循环是非常简单的:

while(!fStop) 
    if(totalLen < BIG_BUFF_LEN-IN_BUFF_LEN) 
    { 
    len=conn.bulkTransfer(epIN, inBuff, IN_BUFF_LEN, 0); 
    System.arraycopy(inBuff, 0, bigBuff, totalLen, len); 
    totalLen+=len; 
    } 

如果你认为这是对arraycopy时间延迟 - 我还是失去了数据,即使我评论说,线路输出。

IN_BUFF_LEN是16384(即使我增加了inBuff的大小,bulkTransfer也不会返回更多值)。

bigBuff是几兆字节。

作为次要的问题 - 没有人知道如何传递一个指针bulkTransfer将直接填充bigBuff ---在一个偏移量(未开始位置“0”

+0

任何解决方案,这一个? – 2012-11-14 16:32:41

+1

也许android在这段时间里是垃圾收集,有些东西正在迷失。检查你的logcat,看看你是否能够在丢失数据时匹配操作系统中发生的事情。 – RightHandedMonkey 2013-01-23 02:26:23

+0

奇怪的问题,因为如果你使用FIFO,它永远不会发生。因为当你读取一个FIFO时,数据就会消失。您是否在每次读取FIFO之前尝试清除缓冲区?即确保您没有两次读取相同的数据,而不是从FIFO中读出,而是在缓冲区中读取。 – fonZ 2013-02-01 10:13:50

回答

0

你必须确保有?没有其他流量 - 在同一总线上 - 优先级高于您的流量

+1

没有其他交通,期间 - 这是一个单一的思想操作。 – Greg 2013-02-18 06:30:01

2

只是为了阐明我尝试的一些方法... USB代码运行在它自己的线程中,并被赋予最大优先级(没有运气) - 我尝试了API调用,libUSB,本机C和其他方法(没有运气) - 我缓冲,轮询和排队(没有运气) - 最终我决定Android无法以“高速”处理USB数据(常量3.2 MB /秒W /无流量控制)。我建一个8MB硬件FIFO缓冲区放入我的设计中以弥补它。 (如果你认为你有一个答案,拿出一些以3.2MB /秒的速度提供数据的东西,看看Android是否可以在没有任何打嗝的情况下处理它,我很肯定它不能。)

1

在Nexus媒体导入器我可以一直推动大约9MB/s,所以它是可能的。我不确定您是否能够控制源代码,但是您可能需要使用某种排序标题将代码分割为16K块,以便可以检测到丢失的块和损坏。

此外,您不检查len < 0.我不确定如果底层堆栈从另一端获取NAK或NYET会有什么结果。我足够了,我有恢复代码来处理这个问题。

我已经看了很长时间,很难找到弥补bulkTransfer目标缓冲区的方法,但我还没有找到它。仅供参考:USBRequest.queue()不尊重ByteBuffer.position()。

无论如何,我有点惊讶,我们可以在bulkTransfer上做16K。根据USB 2.0规范,bulkTransfer端点的最大值应该是512字节。 Android捆绑了BulkTransfers,还是我们违规?

3

@Greg我与全速USB设备有同样的问题,并修复每个轮询之间延迟50毫秒的ANdroid内部USB缓冲区。

3

UsbConnection.bulktransfer(...)是越野车。使用UsbRequest.queue(...)Api。许多人报告说,使用批量转运直接失败了大约1%或2%的投入转移。

+0

UsbRequest.queue(..)是否可以100%正常工作?我也遇到过这样的问题。 – 2016-03-04 11:17:50

+0

我做了一个使用UsbRequest API的usb流量很大的项目。我从未对丢失的数据提出过投诉。不过,我记得我只使用UsbRequest.queue(..)来传入数据。要发送数据,我使用了超时1秒的同步API。使用UsbRequest.queue(..)时,请确保您放入队列的请求与您从队列中收到的请求相同。我还为每个阻止阅读电话创建了一个新请求。 – 2016-03-05 17:38:03

+0

@PabloValdes实现的吞吐量是多少?我遇到了批量问题,并切换到USB请求。我仍然没有得到非常高的速度。你可以分享来源,如果没关系。 – RohitMat 2017-06-12 08:47:05