2012-02-02 20 views
35

Sto provando a ricevere dati da un dispositivo personalizzato basato su un chip FTDI 2232H.Host USB Android - bulkTransfer() sta perdendo dati

Sto utilizzando una semplice modalità FIFO asincrona e la velocità dati in ingresso è di 3,2 MB/sec.

Tutto funziona perfettamente con il codice di prova sul mio PC, ma sto avendo problemi a ricevere dati sul mio Toshiba Thrive.

Il driver Android di TDI non funziona, quindi sto codificando utilizzando Java.

Riesco a ricevere perfettamente il 95% + dei dati, ma di tanto in tanto i dati "sputter" e ottengo parti dello stesso 4-5K di dati due o tre volte, quindi di nuovo a dati buoni.

Non sto andando troppo veloce per il Thrive o per Android, perché in precedenza avevo i dati in arrivo al doppio (6,4 MB/sec) e ne ho ottenuto anche il 95%. (Quindi non dovrebbe avere problemi a metà del tasso.)

Sembra che ci sia una sorta di bug nel buffering (o double-buffering) che avviene all'interno di Android. (Non è il buffer all'interno dell'FTDI 2232H perché i dati ripetuti sono maggiori del buffer interno del chip 4K.)

Il codice di installazione è semplice, e funziona ancora ~ quasi ~ perfettamente.

Il ciclo in cui si verifica l'grab di dati è molto semplice:

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

Nel caso in cui si pensa che è il tempo di ritardo per l'arraycopy - Perdo ancora i dati anche se io commento che la linea fuori.

IN_BUFF_LEN è 16384 (bulkTransfer non restituirà più di quello anche se aumento la dimensione di inBuff).

Il bigBuff è di diversi megabyte.

Come una questione secondaria - qualcuno sa come passare un puntatore a bulkTransfer che popoleranno direttamente bigBuff --- ad un offset (non a partire dalla posizione '0'

+0

qualsiasi soluzione a questo? –

+1

Forse Android è spazzatura in quei momenti e qualcosa si sta perdendo. Controlla il tuo logcat per vedere se è possibile abbinare ciò che sta accadendo nel sistema operativo quando si perdono dati. – RightHandedMonkey

+0

Strano problema, perché se si utilizza un FIFO non dovrebbe mai accadere. Perché quando leggi un FIFO i dati si spengono. Hai provato a cancellare il buffer ogni volta prima di leggere la FIFO? Ad esempio assicurandoti di non leggere gli stessi dati due volte, non dalla FIFO ma dal tuo buffer. – fonZ

risposta

0

Dovete essere sicuri che non ci? non c'è altro traffico - sullo stesso bus - con priorità più alta del tuo traffico

+1

Nessun altro traffico, periodo - questa è un'operazione a senso unico. – Greg

2

Giusto per chiarire alcuni degli approcci che ho provato ... Il codice USB ha funzionato nella sua stessa thread ed è stato dato priorità massima (senza fortuna) - Ho provato le chiamate API, libUSB, nativo C e altri metodi (nessuna fortuna) - Ho bufferizzato, interrogato e messo in coda (senza fortuna) - alla fine ho deciso che Android non poteva gestire i dati USB ad "alta velocità" (costante 3.2) MB/sec senza controllo di flusso). Ho costruito un buffer FIFO hardware da 8 MB nel mio progetto per rimediare. (Se pensi di avere una risposta, trova qualcosa che alimenta i dati a 3,2 MB/sec e vedi se Android può gestirli senza NESSUN singhiozzo. Sono abbastanza sicuro che non sia possibile.)

1

In Nexus Media Importer Posso spingere costantemente circa 9 MB/s, quindi è possibile. Non sono sicuro che tu abbia il controllo della sorgente, ma potresti voler interrompere il feed in blocchi di 16K con una sorta di intestazione in sequenza in modo da poter rilevare blocchi mancanti e danneggiamenti.

Inoltre, non si sta verificando per len < 0. Non sono sicuro di cosa succederà se lo stack sottostante ottiene un NAK o un NYET dall'altra estremità. Ne ho abbastanza che ho il codice di ripristino per gestire questo.

Ho cercato un modo lungo e difficile per compensare il buffer di destinazione bulkTransfer, ma devo ancora trovarlo. A proposito: USBRequest.queue() non rispetta il ByteBuffer.position().

Sono quasi sorpreso di poter fare 16K su bulkTransfer in ogni caso. Secondo la specifica USB 2.0, il massimo dovrebbe essere 512 byte per un endpoint bulkTransfer. Android raggruppa i bulkTransfer o stiamo violando le regole?

3

@Greg Ho lo stesso problema con un dispositivo USB a piena velocità e la correzione doveva includere un ritardo di 50 ms tra ciascun polling al buffer USB interno ANdroid.

3

UsbConnection.bulktransfer (...) è bacato. Usa UsbRequest.queue (...) Api. Molte persone hanno riferito che l'utilizzo di bulk transfer non riesce direttamente attorno all'1% o al 2% dei trasferimenti di input.

+0

UsbRequest.queue (..) funziona al 100% senza esito negativo? Sto anche incontrando quel tipo di problema. –

+0

Ho fatto un progetto che aveva un intenso traffico usb usando l'API UsbRequest. Non ho mai avuto un reclamo sui dati mancanti. Tuttavia, ricordo che uso UsbRequest.queue (..) solo per i dati in entrata. Per inviare i dati ho usato l'API sincrona con timeout 1 secondo. Usando UsbRequest.queue (..) assicurati che la richiesta che hai messo in coda sia la stessa richiesta che ricevi dalla coda. Ho anche creato una nuova richiesta per chiamata di blocco. –

+0

@PabloValdes Qual è stato il throughput raggiunto? Ho affrontato problemi con Bulk e passato alla richiesta usb. Non sto ancora ottenendo velocità molto elevate. Puoi condividere la fonte, se va bene? – RohitMat

Problemi correlati