|
Как побороть большие паузы между запросами к USB драйверу |
|
|
|
Feb 2 2006, 18:53
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-01-06
Из: Украина, Киев
Пользователь №: 12 759

|
Суть проблемы такая: Есть МК (Cygnal C8051F32x) используется одна EP (64+64) с двойной буферизацией передачи типа Bulk на Full Speed в сторону Хоста. К МК должен быть подключен внешний АЦП и Cygnal непрерывно передает данные в сторону хоста. АЦП тактируется примерно 600 КГц и имеет разрядность 12 бит, т.е. Cygnal должен передавать поток 600*1,5 = 900 Кбайт / сек. Если запрос DeviceIoContro(,,,,,0x10000,,) к драйверу (пробовал на WinDriver, USBIO и дровах от Cypress) идет с размером буфера 64К то средняя скорость чтения из EP примерно 1020-1040 Кбайт / сек, т.е. хватает. Но есть ложка дегтя. Если вместо данных АЦП передавать значение внутреннего таймера МК, для проверки задержек, то получается следующая неприятная картина:
[ Пакет №1 – 64 Байта] 6 us – начала записи данных в EP (условно начало передачи пакета) 48 us – окончание записи данных в EP (условно окончание передачи пакета) Время записи = 42 us
[Пауза №1] 48 us … 50 us, dT = 2 us
[ Пакет №2 – 64 Байта] 50 us … 93 us, dT = 43 us
[Пауза №2] 93 us … 3015 us, dT = 2922 us Длина определяется тем, что сначала было записаны первые два пакета в EP (двойная буферизация) после получения команды (по Pipe 00), а дальше пошли IN транзакции от DeviceIoContro(,,,,,0x10000,,).
[ Пакет №3 – 64 Байта] 3015 us … 3057 us, dT = 42 us
[Пауза №3] 3057 us … 3070 us, dT = 13 us
[ Пакет №4 – 64 Байта] 3070 us … 3113 us, dT = 43 us
[Пауза №4] 3113 us … 3128 us, dT = 15 us
Дальше пауз больше нескольких десятков us нет.
[ Пакет №1025 – 64 Байта, т.е. это уже начался новый DeviceIoContro(,,,,,0x10000,,)] dT = 43 us
[Пауза №1025] dT = 10 us
[ Пакет №1026 – 64 Байта] dT = 42 us
[Пауза №1026] >>>>>>>>>>> dT = ~3000 us <<<<<<<<<<<<<
!!! А вот тут не понятно, почему такая огромная пауза? DeviceIoContro(,,,,,0x10000,,) идут просто в цикле кроме этого МК ни чего не получает, неужто драйверу нужно аж 3 ms что бы сформировать DeviceIoContro(,,,,,0x10000,,), причем такая же ситуация на разных драйверах, на разных компах (с 98, 2k и XP c USB1.1. и USB2.0 на борту). Такие большие задержки приводят к тому, что 3000 us / (1/600КГц) = 1800 отсчетов АЦП пролетают, т.е. средняя скорость хорошая, но передачи идут рывками. Если снижать размер буфера, например 8К, задержки в среднем уменьшаются (есть много ~1 ms, но 5% наоборот растут аж до 3-5 ms) и средняя скорость падает почти в 2 раза до ~600 Кбайт / сек
Кто-то сталкивался с такими проблемами? Может кто-то подскажет из-за чего происходят таки большие задержки и как их можно уменьшить?
Пока вижу только один вариант – использовать FIFO.
Спасибо.
|
|
|
|
|
 |
Ответов
|
Feb 3 2006, 14:12
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-01-06
Из: Украина, Киев
Пользователь №: 12 759

|
Спасибо за помощь.
>do{DeviceIOControl} while ()
Я даже об этом не подумал, смотрел что загрузка CPU ~2-3%, и предполагал, что драйвер и Хаб сам все буферизирует на аппаратном уровне чтобы исключить влияние переключение на другие процессы. Заметил если повысить приоритет оболочке, то задержки примерено, постоянны им равны 1,8 мс. Интересно такое пройдет в Win98/ME. Вы не подскажите можно катко поднять приоритет драйверу?
>В подобных случаях используют изохронный режим
Я бы с радостью использовал изохронный режим если бы C8051F32x имел EP большего размера, а то на нем только ~400 KB/s. К сожалению на сайпрес пока не перешел, да и драйвер у них не дружит с Win98/ME.
>буферизация приходящих пакетов производится драйвером Подскажите, пожалуйста, это только для Iso? Драйвер буферизирует все сам или только когда к нему идут запросы, т.е. DeviceIOControl [пауза в проге 3-5 мс] DeviceIOControl, в момент паузы и при отсутствии запроса драйвер будет продолжать принимать пакеты и сохранять их в своем FIFO?
|
|
|
|
|
Feb 3 2006, 16:07
|
Частый гость
 
Группа: Свой
Сообщений: 140
Регистрация: 18-10-05
Пользователь №: 9 792

|
Цитата(msn @ Feb 3 2006, 17:12)  >В подобных случаях используют изохронный режим
Я бы с радостью использовал изохронный режим если бы C8051F32x имел EP большего размера, а то на нем только ~400 KB/s. К сожалению на сайпрес пока не перешел, да и драйвер у них не дружит с Win98/ME. Тот драйвер от Cypress, с которым я начинал в 2001, компилировался в VC6 + DDK98, соответственно под Win98/МЕ. Но неплохо работает и на ХР. Возможно, с тех пор у них появился другой. А нельзя поменять процессор на тот же CYPRESS? Все-таки производительность у него в два раза выше, да и возможностей по прамой передаче АЦП -> USB Engine у CYPRESS'а намного больше. Можно FX2 взять с USB2.0 Цитата(msn @ Feb 3 2006, 17:12)  >буферизация приходящих пакетов производится драйвером Подскажите, пожалуйста, это только для Iso? Драйвер буферизирует все сам или только когда к нему идут запросы, т.е. DeviceIOControl [пауза в проге 3-5 мс] DeviceIOControl, в момент паузы и при отсутствии запроса драйвер будет продолжать принимать пакеты и сохранять их в своем FIFO? В CYPRESS-овом драйвере для ISO организуется очередь IRP-запросов и принятые данные сохраняются в выделенном буфере. Оттуда их можно считать отдельной командой. Т. е., все принятые данные сохраняются в FIFO. Кстати, есть одна особенность - после подачи команды на закрытие потока(IOCTL_EZUSB_STOP_ISO_STREAM), перед повторным запуском чтения надо выдержать время, чтобы все IRP-запросы завершились. Для bulk такого механизма нет, запрос на чтение отправляется сразу в USBD, соответственно паузы между запросами остаются. В других драйверах, я думаю, с bulk поступают аналогичным образом.
Сообщение отредактировал Johny - Feb 3 2006, 16:08
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|