2012-02-02 285 views
35

FTDI 2232Hチップに基づいてカスタムデバイスからデータを受信しようとしています。Android USBホスト - bulkTransfer()がデータを失う

私は単純な非同期FIFOモードを使用しており、入力データレートは3.2MB /秒です。

すべては私のPCのテストコードではうまく動作しますが、私は東芝グライダーでデータを受信する際に問題があります。

TDIのAndroidドライバが失敗するため、Javaを使用してコーディングしています。

私は95%+のデータを完全に受け取ることができますが、しばらくの間、データは「スパッター」し、同じ4-5Kのデータの部分を2〜3回取得してから、良いデータに戻ります。

以前はデータが2倍(6.4MB /秒)で受信していたため、ThriveやAndroidではあまり速く進まず、その約95%も得ました。 (したがって、レートの半分で問題はありません)

Android内で発生するバッファリング(またはダブルバッファリング)に何らかのバグがあるようです。 (繰り返しデータがチップの4K内部バッファよりも大きいため、FTDI 2232H内のバッファではありません)

セットアップコードはシンプルで、やはりほぼ完璧です。

データのグラブが発生したループは非常に簡単です:

場合
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

この回答を解決するには? –

+1

おそらくアンドロイドはこれらの時間の間にガベージコレクションを行い、何かが失われています。あなたがデータを失ったときにOSで起こっていることを突き合わせることができるかどうかについては、logcatを調べてください。 – RightHandedMonkey

+0

奇妙な問題です。なぜなら、FIFOを使用すると決して起こらないはずです。 FIFOを読み込むと、データが消えるからです。あなたはFIFOを読む前に毎回バッファをクリアしようとしましたか?つまり、同じデータをFIFOからではなくバッファから2回読み取らないようにします。 – fonZ

答えて

0

あなたは必ず存在していることでなければなりません?

+1

他のトラフィックはありません。これは単一の操作です。 – Greg

2

私は試したアプローチのいくつかを明確にするために... USBコードはそれ自身のスレッドで実行され、最大優先度を与えられました(運がない) - 私はAPIコール、libUSB、ネイティブC、および他のメソッド(運がない)を試しました - 私はバッファリングされ、ポーリングされ、待ち行列に入りました(最終的にはアンドロイドはUSBデータを '高速' MB/sec(フロー制御なし))。それを補うために私の設計に8MBのハードウェアFIFOバッファを搭載しました。 (もしあなたが答えを持っていると思うなら、3.2MB /秒でデータを提供するものを考えて、Androidが何の問題もなくそれを処理できるかどうかを確かめてください)。

1

Nexusメディアインポーター私は一貫して約9MB/sを押すことができるので、可能です。あなたがソースの制御権を持っているかどうかは分かりませんが、フィードを16Kブロックに分割して、何らかのシーケンスされたヘッダを付けてブロックや破損を検出できるようにすることができます。

また、len <もチェックしていません。基礎となるスタックがもう一方の端からNAKまたはNYETを受け取った場合、どうなるでしょうか。私はこれを処理するためのリカバリコードを持っています。

bulkTransferの宛先バッファをオフセットする方法が長く見えましたが、まだ見つけていません。 FYI:USBRequest.queue()はByteBuffer.position()を尊重しません。

私はバルク転送で16Kを行うことができますと驚いています。 USB 2.0仕様によると、maxはbulkTransferエンドポイントの512バイトとされています。 Androidはバルク転送をバンドルしているのですか、それともルールを破っていますか?

3

@Greg私はフルスピードのUSBデバイスで同じ問題を抱えていますが、各ポーリングとANdroidの内部USBバッファとの間に50msの遅延が含まれていました。

3

UsbConnection.bulktransfer(...)はバグです。 UsbRequest.queue(...)Apiを使用します。 bulktransferを直接使用すると、入力転送の約1%または2%が失敗することが多くの人から報告されています。

+0

UsbRequest.queue(..)は100%正常に動作しますか?私もこの種の問題に遭遇しています。 –

+0

私はUsbRequest APIを使って大量のusbトラフィックを持ったプロジェクトを行った。紛失したデータに対する苦情は一度もありませんでした。しかし、私はUsbRequest.queue(..)を受信データに対してのみ使用することを覚えています。データを送信するために、同期APIをタイムアウト1秒で使用しました。 UsbRequest.queue(..)を使用する場合は、キューに入れた要求がキューから受け取った要求と同じであることを確認してください。私は読書通話をブロックするごとに新しいリクエストを作成しました。 –

+0

@PabloValdes達成されたスループットは?私はバルクで問題に直面し、usbの要求に切り替えました。私はまだ非常に高速になっていません。ソースを共有することはできますか? – RohitMat

関連する問題