2012-06-04 12 views
13

estoy escribiendo software para comunicarse entre tableta (Motorola Xoom con Android versión 4.0.3 y la versión del kernel 2.6.39.4) y un dispositivo periférico usando USB Host API proporcionada por Androide. Puedo utilizar sólo dos tipos de comunicación:Android USB Host API: Transferencia mayor tamaño del búfer

  • de control: controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
  • mayor: bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)

transferencia de control funciona bien, pero tengo un problema con la transferencia a granel. Solo puedo usar 32768 como tamaño del buffer para la función bulkTransfer. No es posible usar menos o más. Sé que no puedo usar más debido al límite de la tubería del búfer (tamaño: 32769 bytes).

Este dispositivo periférico transmite datos que no son leídos correctamente por la función bulkTranfer. Supongo que algunos datos se pierden.

Me parece: In Linux If a process attempts to read from an empty pipe (buffer), then read(2) will block until data is available. If a process attempts to write to a full pipe , then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete.

Y en base a eso, mi explicación del problema es que algunos datos no se escriben a la tubería (tampón) a causa de bloqueo bandera hecha por (2) función de escritura. ¿Estoy en lo correcto? Si esto es cierto, podría cambiar el buffer de tubería.

  1. Mi primera solución para este problema es una mayor memoria intermedia. For kernel >= 2.6.35, you can change the size of a pipe with fcntl(fd, F_SETPIPE_SZ, size), pero ¿cómo puedo encontrar fd (descriptor de archivo) para las tuberías USB ?
  2. La segunda opción es usar ulimit -p SIZE pero el parámetro p para mi kernel no es para pipe sino para proceso.

¿Alguien ha enfrentado el mismo problema, alguna solución?

+0

usando la transferencia masiva, también estoy enfrentando el problema de pérdida de datos. mirándolo. Te lo haré saber una vez que encuentre la causa raíz. sigue actualizando el estado. – yokks

+0

OK, gracias por la información. – syntagma

+0

http://android.serverbox.ch/?p=370 ¿Puedes pasar por esta conversación? aquí se presenta una lógica para manejar datos entrantes. Espero que te ayude. – yokks

Respuesta

2

Usted debe obtener un analizador de datos USB, Im usar éste: http://www.ellisys.com/products/usbex200/index.php

Usando algo como esto realmente me ayudó cuando estaba haciendo el mismo tipo de cosas, lo que encontré fue que había que hacer algún tipo de de while loop.

para mi dispositivo tuve 64 bytes de datos que vienen en paquetes para mí, el paquete sería de dos bytes de control y 62 para los datos, por lo que para mi traslado tenía que hacer algo como

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

algo un Mientras estas líneas funcionaban bien para mí, tenía exactamente el mismo problema y así es como lo solucioné. Tengo más información si la necesitas. Solo comenta :). Sé que esto fue realmente frustrante para mí. Estoy usando un Acer Iconia A500 con Android 4.0.3 BTW


Transferring larger amounts of data USB

Transferring data USB

+0

No tengo ese tipo de dispositivo. Solo usé USBlyzer para verificar la transferencia entre el dispositivo y la plataforma de Windows.No recibo datos de control en bulkTransfer y, probablemente, el tamaño máximo del paquete es de 512 bytes. ¿Tienes alguna sugerencia? – syntagma

0

Según AN232B-04_DataLatencyFlow.pdf, control de flujo es necesario para altas velocidades de datos:

Se recomienda enfáticamente que el control de flujo se utiliza porque es imposible de asegurar que el controlador FTDI siempre se programará.

¿Ha intentado utilizar una de las opciones de control de flujo (RTS/CTS, DTR/DSR, XON/XOFF) para sincronizar sus datos?

+0

No probé el control de flujo. No debería usar ese tipo de solución porque causará latencia adicional. Analicé la transferencia USB entre el dispositivo y la plataforma de Windows y no hay control de flujo. – syntagma

+0

@REACHUS: Mi situación es similar: leer desde el FTDI funciona bien en mi caja de Linux pero pierde datos en la tableta de Android. Como hago unos 400kbps de transferencia continua de datos (grabación de audio a través de USB), sospecho que tal vez la combinación de hardware de la tableta/kernel/controlador se comporte mal en altas velocidades de datos. Al igual que usted, sé que en mi caso de Linux no se realiza control de flujo, pero tal vez en Android las cosas son diferentes, por lo tanto, la recomendación. – gfour

1

De acuerdo con el mismo Gfour .pdf publicado, me encontré con este párrafo ahí:.

"El tamaño del paquete afectará el rendimiento y depende de la velocidad de datos para una velocidad muy alta, el paquete más grande tamaño es necesario. Para aplicaciones en "tiempo real" que transfieren datos de audio a 115200 baudios, por ejemplo, el paquete más pequeño posible es deseable, de lo contrario, el dispositivo retendrá 4k de datos a la vez. Esto puede dar el efecto de ' transferencia brusca de datos si el tamaño de la solicitud USB es demasiado grande y la velocidad de datos demasiado baja (relativamente).

Me encuentro con una situación similar a SmartLemon con un dispositivo serie FTDI, así que he estado buscando formas de aliviarla recientemente. Esto requerirá que escriba mis propias funciones desde cero mientras que antes estaba usando una biblioteca.

Sin embargo, parece que en su caso, podría intentar usar el tamaño de búfer más bajo de bulkTransfer en lugar de disparar a la más grande. Puede que ya hayas intentado esto, pero tal vez no. Veo que dices que 32768 es el único tamaño, pero tal vez solo quisiste decir el máximo. Parece raro que solo permita un tamaño específico.

-1

puede probar esta cuestión de la transferencia a granel

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

      } 
1

UsbEndpoint objeto del SDK de Android proporciona un métodogetMaxPacketSize(), que le permite comprobar lo que es apropiado para su dispositivo. En general, el tamaño máximo de paquete permitido es de 64 bytes para dispositivos USB de "velocidad completa" y de 512 para dispositivos de "alta velocidad", mucho menos de 32,768 que está intentando. ¿Está confundiendo el tamaño del paquete USB subyacente con el de algún protocolo de nivel superior?

Cuestiones relacionadas