2012-02-02 67 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