39 votes

Android USB Host - bulkTransfer () perd des données

Je suis en train de recevoir des données à partir d'un périphérique personnalisé basé sur un FTDI 2232H puce.

Je suis à l'aide d'un simple Asynchrone en mode FIFO, et les données entrantes taux est de 3,2 MO/sec.

Tout fonctionne parfaitement avec des tests de code sur mon PC, mais je vais avoir des problèmes de réception de données sur mon Toshiba Thrive.

TDI Android pilote échoue, donc je suis de codage à l'aide de Java.

Je peux recevoir 95%+ de données parfaitement, mais à chaque fois dans un certain temps les données "crache" et je reçois des portions du même 4-5K de données deux fois, trois fois, puis retour à de bonnes données.

Je ne suis pas aller trop vite pour le développer ou Android, parce que j'ai déjà eu les données en double (6.4 MO/sec) et il a obtenu environ 95% de ce que bien. (Donc il ne devrait avoir aucun problème à la moitié du taux.)

Il semble qu'il y est une sorte de bug dans la mise en mémoire tampon (ou double-buffering) qui se passe à l'intérieur d'Android. (Il n'est pas le tampon à l'intérieur de la FTDI 2232H parce que la répétition de données est plus grand que la puce 4K de mémoire tampon interne.)

Le code d'installation est simple, et c'est encore de travail ~près~ parfaitement.

La boucle où les données à saisir se produit est très simple:

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

Dans le cas où vous pensez que c'est le temps de retard pour la arraycopy - je encore perdre les données, même si je commente cette ligne.

Le IN_BUFF_LEN 16384 (bulkTransfer ne reviendra pas plus que ça, même si je augmenter la taille de la inBuff).

Le bigBuff est de plusieurs méga-octets.

Comme une question secondaire - ce que quelqu'un sait comment passer un pointeur vers bulkTransfer qui remplira bigBuff directement --- à un décalage (pas de départ à la position '0'?

4voto

Pablo Valdes Points 16

UsbConnection.bulktransfer (...) is buggy. Utilisez UsbRequest.queue (...) Api. De nombreuses personnes ont signalé que l’utilisation directe du transfert groupé échouait pour environ 1% ou 2% des transferts d’intrants.

3voto

Pablo Valdes Points 16

@Greg J'ai le même problème avec un périphérique USB à pleine vitesse et le correctif était d'inclure un délai de 50 ms entre chaque scrutation vers le tampon USB interne ANdroid.

2voto

Greg Points 371

Juste pour clarifier un peu les approches, j'ai essayé...L'USB code a couru dans son propre thread et a été donné à max priorité (pas de chance) - j'ai essayé d'appels API, libUSB, C indigènes, et d'autres méthodes (pas de chance), je l'ai mise en mémoire tampon, et l'interrogation, et en file d'attente (pas de chance) - en fin de compte j'ai décidé Android ne pouvait pas supporter de données USB à "haute vitesse" (constant 3.2 MO/s w/ pas de contrôle de flux). J'ai construit une 8MB matériel tampon FIFO dans ma conception de faire pour elle. (Si vous pensez que vous avez une réponse, venir avec quelque chose qui se nourrit de données à 3,2 MO/sec et voir si Android peut le manipuler sans AUCUN problème. Je suis assez sûr qu'il ne peut pas.)

1voto

Dustin Points 286

Nexus Media importer je peux pousser jusqu'a environ 9 MO/s, donc c'est possible. Je ne suis pas sûr si vous avez le contrôle de la source, mais vous pouvez les diviser le flux dans 16K blocs avec une sorte de séquencé en-tête de sorte que vous pouvez détecter des manque des blocs et de la corruption.

Aussi, vous n'êtes pas vérifier pour len < 0. Je ne suis pas sûr de ce que si le sous-jacent de la pile devient un NAK ou NYÉTÉ à partir de l'autre extrémité. Je reçois assez sur ce que j'ai le code de récupération pour gérer cela.

J'ai regardé en long et dur pour un moyen de compenser les bulkTransfer tampon de destination, mais je n'ai pas encore trouver. FYI: USBRequest.la file d'attente() ne respecte pas les ByteBuffer.position().

Je suis un peu surpris que nous pouvons faire 16K sur bulkTransfer de toute façon. Selon l'USB 2.0 spécification, le max est censé être de 512 octets pour un bulkTransfer point de terminaison. Est Android regroupement le la bulkTransfers, ou sommes-nous à enfreindre les règles?

0voto

HaniGamal Points 166

Vous devez vous assurer qu'il n'y a pas d'autre trafic - sur le même bus - avec une priorité plus élevée que votre trafic.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X