13

Android が提供するUSB Host API を使用して、タブレット(Android バージョン 4.0.3 およびカーネル バージョン 2.6.39.4 の Motorola Xoom)と周辺機器の間で通信するためのソフトウェアを作成しています。私は 2 種類の通信のみを使用します。

  • コントロール:controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
  • バルク:bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)

コントロール転送は問題なく動作しますが、一括転送に問題があります。bulkTransfer 関数のバッファーのサイズとして 32768 しか使用できません。少ないまたは多いを使用することはできません。バッファ パイプの制限 (サイズ: 32769 バイト) のため、これ以上使用できないことはわかっています。

この周辺機器は、bulkTranfer 関数によって正しく読み取られないデータをストリーミングします。一部のデータが失われていると思います。

Linux では、プロセスが空のパイプ (バッファ) から読み取ろうとすると、データが利用可能になるまで read(2) がブロックされます。プロセスが満杯のパイプに書き込もうとすると、 write(2) は、パイプから十分なデータが読み取られて書き込みが完了するまでブロックされます。

それに基づいて、問題の私の説明は、 write(2) 関数によって作成されたブロックフラグのために、一部のデータがパイプ (バッファー) に書き込まれないということです。私は正しいですか?これが本当なら、パイプ バッファを変更できます。

  1. この問題に対する私の最初の解決策は、バッファーを大きくすることです。カーネル>= 2.6.35の場合、パイプのサイズを変更できますがfcntl(fd, F_SETPIPE_SZ, size)fd、USBパイプの(ファイル記述子)を見つけるにはどうすればよいですか?
  2. 2番目のオプションは使用することですulimit -p SIZEが、カーネルのパラメーターpはパイプではなくプロセス用です。

誰かが同じ問題に直面しましたか、解決策はありますか?

4

5 に答える 5

2

USB データ アナライザーを入手する必要があります。私はこれを使用しています: http://www.ellisys.com/products/usbex200/index.php

私が同じタイプのことをしていたとき、このようなものを使用すると本当に役に立ちました.

私のデバイスでは、64バイトのデータがパケットに入っていました。パケットは2つの制御バイトとデータ用の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 に答える