Ответ 1
@Greg У меня такая же проблема с устройством с полной скоростью USB, и исправление должно включать задержку в 50 мс между каждым опросом в внутренний буфер usb от ANdroid.
Я пытаюсь получить данные с пользовательского устройства на основе чипа 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"?
@Greg У меня такая же проблема с устройством с полной скоростью USB, и исправление должно включать задержку в 50 мс между каждым опросом в внутренний буфер usb от ANdroid.
UsbConnection.bulktransfer(...)
глючит. Используйте UsbRequest.queue(...)
Api.
Многие люди сообщают, что при непосредственном использовании массового переноса происходит сбой около 1% или 2% входных переводов.
Просто для того, чтобы прояснить несколько подходов, которые я пробовал... USB-код запустил в нем собственный поток и получил максимальный приоритет (не повезло) - я пробовал API-вызовы, libUSB, native C и другие методы (не повезло ) - Я буферизовался, опросил и поставил в очередь (не повезло) - в конечном итоге я решил, что Android не сможет обрабатывать данные USB на "высокой скорости" (постоянный 3,2 МБ/с без управления потоком). Я построил в моем дизайне 8 МБ аппаратный буфер FIFO, чтобы компенсировать это. (Если вы считаете, что у вас есть ответ, придумайте что-то, что подает данные со скоростью 3,2 Мбайт/с и посмотрит, сможет ли Android справиться с ним без каких-либо икота. Я почти уверен, что он не может.)
В 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, или мы нарушаем правила?
Вы должны быть уверены, что нет другого трафика - на той же шине - с более высоким приоритетом, чем ваш трафик.