Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Почему тормозит драйвер USB FT232?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Интерфейсы
aas
Доброе время суток!

Ситуация такая: имеем прибор, который умеет соединяться с ПК через RS232 и USB. Собственно, эти 2 интерфейса, это 2 UART-выхода процессора, которые идут на соответствующие микросхемы-мосты. Разработчики прибора написали в сове время консоль для его настройки, которая взаимодействует с прибором по протоколу WAKE (который тут, как я понимаю, хорошо известен). Консоль написана на Python + dll, написанная автором (как я догадываюсь) этого самого WAKE. Скорость установили аж 115200, хотя RS232-шнур имеет всего 3 жилы, т.е. какое-то управление потоком отсутствует, один конец гонит байты, другой их ловит, как успевает. Но с короткими командами и на не самых древних компах все работает вполне.

Теперь тут, уже у меня, возникла задача сделать сначала средство выкачивания из прибора данных, иногда немаленьких (десятки килобайт). Я для упражнения сначала реализовал на этом же Python соответствующие функции. Это как бы расширение протокола получилось на передачу длинных данных, они все идут с одной командой и циклическим счетчиком пакетов. Вроде работает (собственно, в одну сторону это еще до меня начато было, была функция выкачать на ПК скриншот с прибора). Но поскольку следующая задача - перенести пользовательский интерфейс на ПК или планшетник под андроидом, я написал реализацию этого самого WAKE на Java. И вот тут я наткнулся на неприятный сюрприз: с COM-портом все работает хорошо, а вот с USB (т.е. виртуальный COM через драйвер FT232) иногда запрос чтения из него до 4 мс занимает! Т.е. читать по одному байту в цикле не вариант совершенно, входной буфер переполняется и кранты. Соптимизировал я до чтения одного пакета за 2 приема (сначала читаем FEND+адрес+длину данных (или без адреса в моем случае), потом данные+ CRC, это, конечно, если обошлись без стаффинга), только тогда заработало на скорости порта 115200. Ну то есть на моем компьютере, не первой свежести, конечно, (Pentium E2180, двухядерный 2 ГГц) вроде с запасом работает, но у метрологов (которые основные портебители продукции) могут быть еще более древние компы + параллельно в браузерах крутиться могут какие-нибудь флеш-рекламы... А мне потом еще и на Андройде это все гонять, а там железо еще слабее...

На всякий случай, из Java я обращаюсь к портам через библиотеку jSSC. Понижать скорость не вариант, ибо "хватило ума" у меня сначала доработать прошивку и отправить заказчиками уже несколько приборов с обещанием дослать потом софт для ПК, а они все ушли с зашитой скоростью 115200, и с этой скоростью оно гонит пакеты без всяких промежутков.
Подозреваю, есть решение у автора протокола WAKE в его dll-ках, но их исходников я не нашел sad.gif.

Почему так происходит и что делать? Один вариант я сам придумал - самому буферизовывать порт и читать всегда за один прием все что есть. Есть ли еще варианты?

Спасибо за ответы!
smalcom
Цитата
Я для упражнения сначала реализовал на этом же Python

и как они себя ведут с этим виртуальноым ком-портом? тоже медленно как и в ява-версии?
Lagman
Цитата(aas @ Sep 2 2013, 20:24) *
Скорость установили аж 115200, хотя RS232-шнур имеет всего 3 жилы, т.е. какое-то управление потоком отсутствует, один конец гонит байты, другой их ловит, как успевает. Но с короткими командами и на не самых древних компах все работает вполне.

Вы реально думаете что количество проводов увеличит скорость? sm.gif
Стабильность приема-передачи это отдельная тема и мало зависит от количества проводов. Почитайте документацию на свою микросхемку ftdi, на официальном сайте есть документация по программированию.
smalcom
у меня просто подозрение, что написанное на жабке неадекватно.
=AK=
Цитата(aas @ Sep 3 2013, 01:54) *
возникла задача сделать сначала средство выкачивания из прибора данных, иногда немаленьких (десятки килобайт).

В CDC драйвере Винды имеется баг. Этот драйвер использует кольцевой буфер размером 8 КБ, а баг связан с "закольцовкой" этого буфера. То есть, передавать массивы меньше 8 КБ - нет проблем, или передавать большие массивы кусками размером не более 8 КБ - тоже нет проблем. А вот единый массив большого массива передавать не получается, данные портятся.

Я это обнаружил когда читал данные из EEPROM по I2C и кидал их в комп через USB CDC по протоколу типа WAKE. Чтобы удостовериться, протестировал обмен на демо версии драйвера Thesycon. С ним проблем никаких, все работает как часы, но дорогой, зараза. А с родным мелкософтовским - глючит при размере массива более 8 КБ.
aas
Цитата(smalcom @ Sep 2 2013, 22:27) *
и как они себя ведут с этим виртуальноым ком-портом? тоже медленно как и в ява-версии?


Нормально ведет себя, если через DLL от разработчика протокола. Но мой вариант с двумя чтениями на пакет тоже нормально ведет, на моем компьютере, а на более медленных пока не имел возможности потестировать. Может быть, автор DLL тоже так жде поступил, минимизировал количество обращений, и 4 мс на обращение не проблема пока, но может быть он и еще как-то хитрее сделал, увы, у меня нет исходников.

Цитата(Lagman @ Sep 3 2013, 00:27) *
Вы реально думаете что количество проводов увеличит скорость? sm.gif
Стабильность приема-передачи это отдельная тема и мало зависит от количества проводов. Почитайте документацию на свою микросхемку ftdi, на официальном сайте есть документация по программированию.


Насколько я понимаю, через дополнительные провода его можно тормознуть, если что, а значит можно на большие запасы по времени не закладываться для надежности, и потому можно скорость больше.

Цитата(smalcom @ Sep 3 2013, 01:06) *
у меня просто подозрение, что написанное на жабке неадекватно.


Вроде все обнюхал и прошел отладчиком вдоль и поперек, и в реальном времени через вывод логов тоже, не знаю что там неадекватного может быть. Да и работает же, если достаточно быстрая реакция. Ну а медленная реакция если, по 3 проводам не тормознешь поток все равно.

Цитата(=AK= @ Sep 3 2013, 05:07) *
В CDC драйвере Винды имеется баг. Этот драйвер использует кольцевой буфер размером 8 КБ, а баг связан с "закольцовкой" этого буфера. То есть, передавать массивы меньше 8 КБ - нет проблем, или передавать большие массивы кусками размером не более 8 КБ - тоже нет проблем. А вот единый массив большого массива передавать не получается, данные портятся.

Я это обнаружил когда читал данные из EEPROM по I2C и кидал их в комп через USB CDC по протоколу типа WAKE. Чтобы удостовериться, протестировал обмен на демо версии драйвера Thesycon. С ним проблем никаких, все работает как часы, но дорогой, зараза. А с родным мелкософтовским - глючит при размере массива более 8 КБ.


Да вроде если читать быстро, оно не имеет проблем, и система сама не дает буфер более 4 К поставить. Пока буфер не переполнен, все хорошо, ну а если переполнен, ошибка сразу, или CRC или потерянный пакет выскакивает. Хотя, тут как-то странно все, у меня и дома и на работе XP, правда, на работе XP home русская, а дома XP professional английская. Обе регулярно одновляются. Но окошки настройки параметров порта принципиально разные. На работе окно где много параметров в выпадающих списках, в том числе и размер порта, а дома в окне 2 каких-то слайдера непонятного назначения типа "больше-меньше", вроде тоже размер буфера определяют, но в каких единицах они неясно.
ar__systems
CDC тут не причем FTDI свои драйвера использует. Зайдите в настройки порта, Девайс манаджер, порт, сеттингс, адвансед. Там есть таймауты, их надо уменьшить. С собой нет портов, не помню точно там установку по памяти какую менять.
Raven
Цитата(aas @ Sep 3 2013, 10:42) *
Вроде все обнюхал и прошел отладчиком вдоль и поперек, и в реальном времени через вывод логов тоже, не знаю что там неадекватного может быть. Да и работает же, если достаточно быстрая реакция. Ну а медленная реакция если, по 3 проводам не тормознешь поток все равно.

Вообще-то, тормознешь, но с соответствующей программной поддержкой. Есть же такая штука - XON/XOFF управление потоком (для 3-проводных вариантов, где аппаратное управление не предусмотрено). Но поскольку вы уже отгрузили "торопливый" вариант, то похоже, единственный вариант - выгребать приложением все, что только идет из драйвера, буферизировать у себя, и делать это "бистро-бистро" sm.gif. А какой размер всей посылки-то? И еще вопрос. Если глянуть на схему прибора повнимательнее - нет ли аппаратного управления потоком в направлении UART-USB? Может, оно только на направлении UART-RS232 отсутствует?

Ну, а насчет задержек в 4 мс - чего ж вы хотите, если в Full Speed USB (12 Mbps) периодичность обмена (продолжительность кадра) - 1 мс? Обмен малыми порциями - это не для USB.
редактор
Хочу добавить немного арифметики
За 1 мс из МК в USB мост можно передать 11,5 байт (115200/10)/1000 (без учета паузы между байтами)
Чтобы набрать буфер 8К необходимо 8196/11 ~ 740 мс.
Достаточно по таймеру раз в 20-50 мс производить чтение данных с порта, фактически из буфера драйвера поскольку FTDI отдает эти данные по мере готовности.
Другое дело если FTDI тормозит с отдачей данных в ПК (маленький внутренний буфер может быть).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.