Android - 丢失传入(高速)USB数据

时间:2012-02-23 01:07:12

标签: android usb real-time

使用Android时,我丢失了传入USB数据流的数据,在Windows中读取相同的设备/流时,我不会丢失这些数据。 (我知道Android不是一个实时操作系统,但Windows也不是,Windows也没有问题'跟上'数据。)

我使用内置4K缓冲区的FTDI 2232H芯片以大约3.5MB /秒的速度传输数据。 libusb中的bulk_transfer调用一次可以请求16K,因此Android需要每4ms左右收集一次USB缓冲区的内容。

我尝试过:用Java和C语言编写,将线程(和/或进程)优先级提高到最高,同步和异步例程,我甚至为每个USB读取传递一个单独的缓冲区,所以我甚至都没有必须在连续读取之间复制数据。 (在传输过程中没有垃圾收集。)我只需要缓冲20MB的数据,所以这都是RAM。

尽管如此,Android还没有“绕过”USB数据,有时候读取间隔时间长达12毫秒,导致大量数据丢失。

有没有人有任何想法? DMA?对内核有某种“实时”请求?

1 个答案:

答案 0 :(得分:5)

我之前遇到过这种问题。忘记使用Java,在后台它正在做大量阻止实时访问的事情,例如:垃圾收集,线程处理。同样忘记使用事件驱动编程,即使在高优先级线程中,也可能需要很长时间才能处理事件并且您可能会丢失数据。

我修复它的方式是编写“不友好”的代码!使用C或汇编,并写了这样的轮询函数(在类似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;
}

你提到你试过C,所以将它转换成实际函数应该很简单。避免使用便利功能的诱惑,您希望尽可能接近金属。例如。如果O / S函数Read()依次调用read()而后调用_read(),则您希望使用_read()。 在这种情况下,设备会明显变慢,但这是实时访问的权衡。