2012-02-02 12 views
35

Estoy tratando de recibir datos de un dispositivo personalizado basado en un chip FTDI 2232H.Android USB Host - bulkTransfer() está perdiendo datos

Estoy utilizando un modo Async FIFO simple, y la velocidad de datos entrantes es de 3.2MB/seg.

Todo funciona perfectamente con el código de prueba en mi PC, pero estoy teniendo problemas para recibir datos en mi Toshiba Thrive.

El controlador de Android de TDI falla, entonces estoy codificando usando Java.

Puedo recibir el 95% + de los datos perfectamente, pero de vez en cuando los datos 'sputters' y yo recibimos porciones de los mismos 4-5K de datos dos o tres veces, luego regresamos a buenos datos.

No estoy yendo demasiado rápido para Thrive o Android, porque previamente tenía los datos en doble (6.4MB/seg) y obtuvo aproximadamente el 95% de eso también. (Así que no debería tener ningún problema a la mitad de la velocidad).

Parece que hay algún tipo de error en el almacenamiento en búfer (o doble buffering) que ocurre dentro de Android. (No es el buffer dentro del FTDI 2232H porque los datos repetidos son más grandes que el buffer interno 4K del chip).

El código de configuración es simple, y de nuevo está funcionando ~ casi ~ perfectamente.

El bucle donde se produce la apropiación de los datos es muy 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; 
    } 

En caso de que creo que es el tiempo de retardo para el arraycopy - Todavía perder los datos, incluso si comento esa línea.

El IN_BUFF_LEN es 16384 (bulkTransfer no devolverá más que eso, incluso si aumente el tamaño del inBuff).

El bigBuff es de varios megabytes.

Como una cuestión secundaria - ¿alguien sabe cómo pasar un puntero a bulkTransfer que poblarán bigBuff directamente --- en un desplazamiento (no comienza en la posición '0'

+0

alguna solución a esta? –

+1

Quizás Android es la recolección de basura durante esos tiempos y algo se está perdiendo. Compruebe su Logcat para ver si puede coincidir con lo que está sucediendo en el sistema operativo cuando pierde datos. – RightHandedMonkey

+0

Problema extraño, porque si usa un FIFO nunca debería suceder. Porque cuando lee un FIFO, los datos se apagan. ¿Has intentado borrar el buffer cada vez antes de leer el FIFO? es decir, asegurarse de no leer los mismos datos dos veces, no fuera del FIFO sino de su búfer. – fonZ

Respuesta

0

Tienes que estar seguro de que hay? no hay otro tráfico - en el mismo autobús - con mayor prioridad que su tráfico.

+1

No hay otro tráfico, punto: esta es una operación de una sola idea. – Greg

2

Solo para aclarar algunos de los enfoques que probé ... El código USB funcionaba en su propio hilo y se le daba máxima prioridad (sin suerte) - Intenté llamadas a API, libUSB, C nativo y otros métodos (sin suerte) - guardé en búfer, y sondeé, y en cola (sin suerte) - finalmente decidí que Android no podía manejar datos USB a 'alta velocidad' (constante 3.2 MB/s sin control de flujo). Construí un búfer FIFO de hardware de 8 MB en mi diseño para compensarlo. (Si cree que tiene una respuesta, proponga algo que alimente datos a 3.2MB/seg y vea si Android puede manejarlo sin CUALQUIER inconveniente. Estoy bastante seguro de que no puede).

1

En Nexus Importador de medios Puedo empujar consistentemente alrededor de 9 MB/s, por lo que es posible. No estoy seguro si tienes el control de la fuente, pero es posible que desees dividir la fuente en bloques de 16K con algún tipo de encabezado secuenciado para que puedas detectar los bloques faltantes y la corrupción.

Además, no está comprobando si len < 0. No estoy seguro de lo que tendrá si la pila subyacente obtiene un NAK o NYET del otro extremo. Entiendo esto lo suficiente como para que tenga un código de recuperación para manejar esto.

He buscado mucho para resolver el búfer de destino bulkTransfer, pero todavía no lo he encontrado. FYI: USBRequest.queue() no respeta la ByteBuffer.position().

Estoy sorprendido de que podamos hacer 16K en bulkTransfer de todos modos. De acuerdo con la especificación USB 2.0, se supone que el máximo es de 512 bytes para un punto final bulkTransfer. ¿Android está agrupando bulkTransfers o estamos incumpliendo las reglas?

3

@Greg Estoy teniendo el mismo problema con un dispositivo usb de velocidad completa y la solución era incluir un retraso de 50 ms entre cada votación en el buffer USB interno de ANdroid.

3

UsbConnection.bulktransfer (...) tiene errores. Use UsbRequest.queue (...) Api. Muchas personas han informado que el uso de bulktransfer directamente falla alrededor del 1% o 2% de las transferencias de entrada.

+0

¿UsbRequest.queue (..) funciona al 100% sin fallas? También estoy encontrando ese tipo de problema. –

+0

Hice un proyecto que tenía un tráfico usb pesado usando la API UsbRequest. Nunca tuve una queja sobre datos faltantes. Sin embargo, recuerdo que utilizo UsbRequest.queue (..) solo para datos entrantes. Para enviar datos, utilicé la API síncrona con tiempo de espera de 1 segundo. Cuando use UsbRequest.queue (..) asegúrese de que la solicitud que ingresa en la cola sea la misma que recibe de la cola. También creé una nueva solicitud por llamada de lectura de bloqueo. –

+0

@PabloValdes ¿Cuál fue el rendimiento alcanzado? Enfrenté problemas con Bulk y cambié a la solicitud de USB. Todavía no estoy obteniendo velocidades muy altas. Puedes compartir la fuente, si está bien. – RohitMat

Cuestiones relacionadas