Подтвердить что ты не робот

Android USB Host - bulkTransfer() потеряет данные

Я пытаюсь получить данные с пользовательского устройства на основе чипа FTDI 2232H.

Я использую простой режим Async FIFO, а скорость входящей передачи составляет 3,2 МБ/с.

Все работает отлично с тестовым кодом на моем ПК, но у меня проблемы с получением данных на моем Toshiba Thrive.

Драйвер TDI Android не работает, поэтому я кодирую с использованием Java.

Я могу получить 95% + данных отлично, но каждый раз данные "разбрызгиваются", и я получаю части из тех же 4-5K данных два или три раза, а затем обратно к хорошим данным.

Я не буду слишком быстрым для Thrive или Android, потому что раньше у меня были данные, поступающие в двойном (6,4 МБ/сек), и у него было около 95% этого. (Таким образом, у него не должно быть проблем с половиной скорости.)

Кажется, что есть некоторая ошибка в буферизации (или двойной буферизации), которая происходит в Android. (Это не буфер в FTDI 2232H, поскольку повторяющиеся данные больше, чем внутренний буфер 4K).

Код настройки прост, и снова он работает почти ~ идеально.

Цикл, в котором происходит захват данных, очень прост:

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

Если вы считаете это временной задержкой для arraycopy - я все еще теряю данные, даже если я прокомментирую эту строку.

IN_BUFF_LEN - 16384 (bulkTransfer не вернется больше, даже если я увеличиваю размер inBuff).

BigBuff - это несколько мегабайт.

В качестве второстепенного вопроса - кто-нибудь знает, как передать указатель на bulkTransfer, который будет заполнять bigBuff напрямую --- при смещении (не начиная с позиции "0"?

4b9b3361

Ответ 1

@Greg У меня такая же проблема с устройством с полной скоростью USB, и исправление должно включать задержку в 50 мс между каждым опросом в внутренний буфер usb от ANdroid.

Ответ 2

UsbConnection.bulktransfer(...) глючит. Используйте UsbRequest.queue(...) Api.

Многие люди сообщают, что при непосредственном использовании массового переноса происходит сбой около 1% или 2% входных переводов.

Ответ 3

Просто для того, чтобы прояснить несколько подходов, которые я пробовал... USB-код запустил в нем собственный поток и получил максимальный приоритет (не повезло) - я пробовал API-вызовы, libUSB, native C и другие методы (не повезло ) - Я буферизовался, опросил и поставил в очередь (не повезло) - в конечном итоге я решил, что Android не сможет обрабатывать данные USB на "высокой скорости" (постоянный 3,2 МБ/с без управления потоком). Я построил в моем дизайне 8 МБ аппаратный буфер FIFO, чтобы компенсировать это. (Если вы считаете, что у вас есть ответ, придумайте что-то, что подает данные со скоростью 3,2 Мбайт/с и посмотрит, сможет ли Android справиться с ним без каких-либо икота. Я почти уверен, что он не может.)

Ответ 4

В Nexus Media Importer я могу последовательно проталкивать около 9 МБ/с, так что это возможно. Я не уверен, что у вас есть контроль над источником, но вы можете разбить канал на блоки 16K с каким-то секвенсорным заголовком, чтобы вы могли обнаружить недостающие блоки и коррупцию.

Кроме того, вы не проверяете len < 0. Я не уверен, что будет, если базовый стек получит NAK или NYET с другого конца. Я получаю это достаточно, что у меня есть код восстановления, чтобы справиться с этим.

Я искал долго и упорно способ смещения буфера назначения bulkTransfer, но я до сих пор найти его. FYI: USBRequest.queue() не учитывает ByteBuffer.position().

Я удивлен, что мы можем делать 16K на bulkTransfer в любом случае. Согласно спецификации USB 2.0, max должен быть 512 байт для конечной точки bulkTransfer. Является ли Android комплектом bulkTransfers, или мы нарушаем правила?

Ответ 5

Вы должны быть уверены, что нет другого трафика - на той же шине - с более высоким приоритетом, чем ваш трафик.