msn 0 2 февраля, 2006 Опубликовано 2 февраля, 2006 · Жалоба Суть проблемы такая: Есть МК (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. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleks17 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 · Жалоба Не до конца вник, но вопрос такой: т.е. на ПК выполняеется программа: do{DeviceIOControl} while () А как же насчет вытесняющей многозадачности Windows. Т.е. между этими двумя строками программы рально могут выплняться другие процессы с задержками до нескольких десятков мс. Выход - только FIFO. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Abo 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 · Жалоба В подобных случаях используют изохронный режим, в котором гарантируется пропускная способность шины и буферизация приходящих пакетов производится драйвером, ну например как у EzUsb от сайпреса. В вашем случае это вполне реализуемо. Но придется смириться с возможным пропаданием фреймов из-за помех. Изохронные каналы не гарантируют безошибочную передачу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msn 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 · Жалоба Спасибо за помощь. >do{DeviceIOControl} while () Я даже об этом не подумал, смотрел что загрузка CPU ~2-3%, и предполагал, что драйвер и Хаб сам все буферизирует на аппаратном уровне чтобы исключить влияние переключение на другие процессы. Заметил если повысить приоритет оболочке, то задержки примерено, постоянны им равны 1,8 мс. Интересно такое пройдет в Win98/ME. Вы не подскажите можно катко поднять приоритет драйверу? >В подобных случаях используют изохронный режим Я бы с радостью использовал изохронный режим если бы C8051F32x имел EP большего размера, а то на нем только ~400 KB/s. К сожалению на сайпрес пока не перешел, да и драйвер у них не дружит с Win98/ME. >буферизация приходящих пакетов производится драйвером Подскажите, пожалуйста, это только для Iso? Драйвер буферизирует все сам или только когда к нему идут запросы, т.е. DeviceIOControl [пауза в проге 3-5 мс] DeviceIOControl, в момент паузы и при отсутствии запроса драйвер будет продолжать принимать пакеты и сохранять их в своем FIFO? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Abo 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 · Жалоба Да действительно - сигнал не подойдет для длинных изохронных передач. При двойной буферизации размер одного фрейма не более 256 байт. Обратите внимание на TUSB от TI и на сайпресовские изделия. В них поток данных можно пустить мимо процессора через ПДП между буфером эндпоинта и периферией. Про EzUsb. В этом драйвере можно запустить отдельный поток, которому выделить память для кольцевого буфера на приходящие пакеты только по изохронным каналам. Драйвер будет вызывать коллбек при наличии данных. Частота вызова коллбека настраивается при запуске. Можно вызывать например каждый 32 фрейм, то есть раз в 32 мс. Пока перерабатываешь, текущие пакеты складываются самим драйвером. Но, к сожалению такой режим возможен только для ISO IN PIPES. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johny 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 (изменено) · Жалоба >В подобных случаях используют изохронный режим Я бы с радостью использовал изохронный режим если бы C8051F32x имел EP большего размера, а то на нем только ~400 KB/s. К сожалению на сайпрес пока не перешел, да и драйвер у них не дружит с Win98/ME. Тот драйвер от Cypress, с которым я начинал в 2001, компилировался в VC6 + DDK98, соответственно под Win98/МЕ. Но неплохо работает и на ХР. Возможно, с тех пор у них появился другой. А нельзя поменять процессор на тот же CYPRESS? Все-таки производительность у него в два раза выше, да и возможностей по прамой передаче АЦП -> USB Engine у CYPRESS'а намного больше. Можно FX2 взять с USB2.0 >буферизация приходящих пакетов производится драйвером Подскажите, пожалуйста, это только для Iso? Драйвер буферизирует все сам или только когда к нему идут запросы, т.е. DeviceIOControl [пауза в проге 3-5 мс] DeviceIOControl, в момент паузы и при отсутствии запроса драйвер будет продолжать принимать пакеты и сохранять их в своем FIFO? В CYPRESS-овом драйвере для ISO организуется очередь IRP-запросов и принятые данные сохраняются в выделенном буфере. Оттуда их можно считать отдельной командой. Т. е., все принятые данные сохраняются в FIFO. Кстати, есть одна особенность - после подачи команды на закрытие потока(IOCTL_EZUSB_STOP_ISO_STREAM), перед повторным запуском чтения надо выдержать время, чтобы все IRP-запросы завершились. Для bulk такого механизма нет, запрос на чтение отправляется сразу в USBD, соответственно паузы между запросами остаются. В других драйверах, я думаю, с bulk поступают аналогичным образом. Изменено 3 февраля, 2006 пользователем Johny Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msn 0 3 февраля, 2006 Опубликовано 3 февраля, 2006 · Жалоба Большое спасибо за помощь. Узнал много нового и полезного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться