2012-02-23 9 views
33

Quando si utilizza Android, sto perdendo i dati su un USB Flash in entrata torrente che non perdo durante la lettura lo stesso dispositivo/flusso in Windows. (So ​​che Android non è un sistema operativo in tempo reale, ma nessuno dei due è Windows e Windows non ha problemi a "stare dietro" con i dati.)Android - Perdere in entrata (Hi-Speed) dati USB

I dati arrivano a circa 3,5 MB/sec utilizzando un Chip FTDI 2232H che ha un buffer 4K incorporato. Le chiamate bulk_transfer in libusb possono richiedere 16K alla volta, quindi Android deve raccogliere i contenuti del buffer USB ogni 4 ms circa.

Ho provato: scrivere in Java e in C, innalzando la priorità del thread (e/o del processo) alle sue più alte, sincronizzazioni e procedure asincrone, e ho anche passato un buffer separato per ogni lettura USB in modo da non anche a copiare i dati tra letture successive. (Non è in corso alcuna raccolta di dati inutili durante il trasferimento.) Ho solo bisogno di bufferizzare 20 MB di dati, quindi è tutto in RAM.

Ancora, Android è 'non andare in giro' per i dati USB, a volte in attesa finché 12ms tra letture, causando un po 'di perdita di dati.

Qualcuno ha qualche idea? DMA? Una sorta di richiesta "in tempo reale" al kernel?

+0

Che tipo di telefono hai, quale versione di Android, ecc. – PearsonArtPhoto

+0

Due tablet, un Toshiba Thrive e un trasformatore ASUS, entrambi con Android 3.2.1, entrambi con il root. (Scusa se ho dimenticato di menzionarlo nel post originale.) – Greg

+0

@Greg Ho esattamente lo stesso problema (http://stackoverflow.com/questions/10889461/android-usb-host-api-bulk-transfer-buffer-size). Hai trovato qualche soluzione? – syntagma

risposta

5

ho incontrato questo tipo di problema prima. Dimentica l'utilizzo di Java, in sottofondo sta facendo un numero indicibile di cose che impediscono l'accesso in tempo reale, ad es. raccolta dei rifiuti, elaborazione dei thread. Inoltre, dimentica di utilizzare la programmazione basata sugli eventi, anche nei thread con priorità alta, può richiedere molto tempo prima che l'evento venga elaborato e puoi perdere i dati.

Il modo in cui ho fissato era di scrivere codice "ostile"! Usato C o il montaggio, e hanno scritto una funzione di polling come questo (in pseudo-codice C-like):

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

Lei ha detto si è tentato C, quindi dovrebbe essere semplice per convertire questo per funzioni reali. Evita la tentazione di utilizzare le funzioni di convenienza, vuoi il più vicino possibile al metallo. Per esempio. se una funzione O/S Read() a sua volta chiama read() che a sua volta chiama _read(), si desidera di utilizzare _read(). Il dispositivo sarà notevolmente più lento mentre sta procedendo, ma questo è il compromesso dell'accesso in tempo reale.

+1

Non posso credere di non aver provato 'REALTIME' --- la documentazione mi ha portato a credere che l'impostazione di priorità massima fosse 'URGENT_AUDIO' (-19 invece di -20). Avendo risolto questo problema in hardware, potrei non avere la possibilità di provare "REALTIME", ma se lo faccio, posterò i risultati qui. (Vedi sopra la risposta a 'dragonroot'.) – Greg

+0

Come sto anche andando a provare a risolvere [il mio problema] (http://stackoverflow.com/questions/10889461/android-usb-host-api-bulk-transfer-buffer- dimensione) in questo modo, potresti approfondire un po 'questa soluzione? Quanto della tua soluzione completa è stata scritta in C (dove ci sono altre funzioni oltre a quella che hai citato e quelle che usa)? Hai avuto problemi dopo averlo collegato con la tua applicazione Java usando NDK? – syntagma

+0

Quali dispositivi sono stati utilizzati per il test? – syntagma

Problemi correlati