Android: perdiendo los datos USB entrantes (alta velocidad)

Cuando uso Android, estoy perdiendo datos de una corriente de datos USB entrante que no pierdo al leer el mismo dispositivo / flujo en Windows. (Sé que Android no es un sistema operativo en tiempo real, pero tampoco lo es Windows y Windows no tiene ningún problema para mantenerse al día con los datos).

Tengo datos que vienen adentro en cerca de 3.5MB / sec usando un microprocesador de FTDI 2232H que tenga un amortiguador incorporado 4K. Las llamadas de bulk_transfer en libusb pueden pedir 16K a la vez, por lo que Android necesita recoger el contenido del búfer USB cada 4ms o menos.

He intentado: escribir en Java y en C, elevar la prioridad de hilo (y / o proceso) a sus rutinas más altas, sincronizadas y asíncronas, e incluso pasar un búfer separado para cada lectura USB, así que ni siquiera tengo que copiar Datos entre lecturas sucesivas. (No hay recolección de basura en curso durante la transferencia.) Sólo necesito almacenar 20 MB de datos, por lo que es todo a RAM.

Aún así, Android es "no darse la vuelta" a los datos USB, a veces esperando hasta 12ms entre lecturas, causando un montón de datos que se pierden.

¿Alguien tiene alguna idea? DMA? ¿Algún tipo de solicitud 'en tiempo real' al kernel?

He encontrado este tipo de problema antes. Olvidar el uso de Java, en el fondo está haciendo una cantidad incalculable de cosas que impiden el acceso en tiempo real, por ejemplo, recolección de basura, procesamiento de hilos. También olvide utilizar la programación dirigida por eventos, incluso en subprocesos de alta prioridad, puede tardar mucho tiempo antes de procesar el evento y puede perder datos.

La forma en que lo arreglaron fue escribir código "antipático"! Usado C o ensamblado, y escribió una función de sondeo como ésta (en pseudocódigo de tipo C):

#define PAUSE 2 /* Check twice as often as the packet rate */ #define TIMEOUT (500 / PAUSE) /* Abort if half a second of no data */ /* Provide handle, data buffer and size of buffer Returns TRUE if full buffer read, FALSE if not, data unread in size */ BOOL real_time_read(HANDLE handle, BYTE *data, size_t *size) { BOOL result = FALSE; int timeout = TIMEOUT; set_thread_priority(REALTIME); while (is_handle_valid(handle)) { if (is_data_pending(handle)) { size_t count = get_data(handle, data, size); data += count; *size -= count; if (!*size) { result = TRUE; break; } } else if (!--timeout) break; /* Give a tiny time slice to other processes */ usleep(PAUSE); } return result; } 

Usted mencionó que probó C, por lo que debería ser sencillo convertirlo en funciones reales. Evite la tentación de utilizar las funciones de conveniencia, que desea tan cerca del metal como sea posible. Por ejemplo, si una función O / S Read() a su vez llama a read() que a su vez llama a _read() , quiere usar _read() . El dispositivo será notablemente más lento mientras esto sucede, pero esa es la compensación del acceso en tiempo real.

  • Android: api a dispositivos usb externos para aplicaciones robóticas
  • Modo host Android y modo accesorio
  • USB Accessory API en el Samsung Galaxy S2 Android
  • Android: Comunicación con un dispositivo USB que actúa como host
  • Problemas de conexión de Android 6 Nexus 5 USB
  • Android host USB leer desde el dispositivo
  • Comunicación USB de Android
  • Android en los archivos de lista de modo de host Usb en pendrive
  • Comunicación con el host USB de Android
  • ¿Cómo configurar el modo de conexión USB?
  • Enviar mensajes MIDI por USB en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.