Как стать автором
Обновить

Учимся работать с USB-устройством и испытываем систему, сделанную на базе контроллера FX3

Время на прочтение20 мин
Количество просмотров28K
Всего голосов 18: ↑17 и ↓1+16
Комментарии12

Комментарии 12

Спасибо!
1) Я не совсем понял зачем вам WinUSB, почему CyUSB не использовать, тем более что исходники и примеры для Streamer и CxControl доступны. Кроссплатформенность?
2) Драйвер вы загружаете при старте ОС или как службу? Надо бы его выгружать и все хуки отключать в нём даже при аварийном завершении приложения.
3) А чтобы с буферами и FIFO не было переполнений, то там же флаги есть, они аппаратно рулят и могут просигналить/тормознуть при заполнении или GPIF настроить (не помню).
1) В этой статье я постарался раскрыть тему про работу USB вообще, а не про Кипарисов в частности. Вот завтра придётся пользоваться чем-то другим, и как людям быть? Проще взять драйвер, который будет работать с любым чипом. Кипарисы ограничились своими (как минимум, лицензионно)… Как хотят. Ну, и плюс да, формально эта система может попасть в следующую версию нашего комплекса Redd, про который был предыдущий цикл статей. А там базовая ОС — Linux. Так что libusb тут идеален. Он везде подойдёт.

При этом упомянуть существование CyUSB (и CyAPI) было нужно. Вдруг кто-то решит, что ему это подходит и дальше разберётся по документации? Во времена FX2LP я сам только так и работал.

2) Хоть WinUsb, хоть CyUSB, хоть UsbDK по умолчанию грузятся при старте ОС обычно. Если дадите ссылку на описание Вашего варианта, чтобы было ясно, как настроить и как действовать — будет полезно.

3) Конечная цель цикла — разработка анализатора с потоковой передачей данных, без буферизации на самой плате. Верхний предел скорости известен. ULPI тактируется частотой 60 МГц. Голова выдаёт 16 разрядные данные. Итого 120 миллионов байт в секунду. Если бы система не прогоняла через себя такой поток — дальше в неё играть было бы бесполезно. Вариант с буферным SDRAM уже есть, он описывался в нескольких статьях предыдущего цикла про Redd, а прогнать из SDRAM в PC можно и через USB 2.0. Так что надо было или 120, или нисколько. К счастью, всё прокачалось без потерь. Правда, с данными, которые могут то начать течь, то остановиться — есть ещё одна весёлость, о ней я расскажу отдельно.
1)
«Проще взять драйвер, который будет работать с любым чипом.»
Не так много контроллеров с поддержкой USB 3.0+. Я кроме Fx3 не знаю ничего доступного. Ну, а если ограничиться USB 2.0, то согласен с вами.

2) Посмотрите этот пример от Microsoft.
Ну, мне доводилось работать с переходниками USB3 в SATA на уровне конечных точек, чтобы BADы на диске не приводили к проблемам.

Что же до примера — мне почему-то кажется, что правильно спроектированный драйвер USB должен все зачистки производить по событию «отключилось приложение». Мало того, при выдёргивании-то уж из разъёма, сама система всё должна зачистить. Так что мне кажется, что этот вариант — уже излишество. Как минимум — никто же в жизни так не делает. Или, по крайней мере, мне не известно, чтобы делал. Всегда Windows даже если узнает устройство в новом разъёме — стремится установить его драйвер. Жёлтые восклицательные знаки в диспетчере устройств Windows — скорее исключение, чем правило, значит, драйвер старается быть установленным. Хотя, здесь всё это — не догма. Если окажется, что кто-то так делает — я сначала пощупаю на практике, а потом уже буду какие-то выводы для себя делать. Но пока не встречал именно для USB.

Что же до фильтра UsbDK- скорее всего, виновато именно то, что он хранит свои собственные списки, поэтому выдёргивание-вставка устройства и не помогает. Причём исходники у него открытые, наверняка всё можно поправить. Но внутри он достаточно сложен, поэтому на разбирательство нет времени.
Спасибо за статью!
Жду следующую часть!

На всякий случай: у libusb тоже (как и у WinUSB/CyUSB) есть асинхронное API (libusb_submit_transfer и компания). В случае с чтением одиночного куска разницы нет, а вот при длинных передачах разница в скорости между вызовом синхронной функции в цикле и поддержанием очереди из нескольких асинхронных транзакций может быть значительной.

Ага, я начерно уже играл в это для изохронных транзакций, чтобы ловить бесконечный поток аудио. Начисто, с замерами для Bulk — чуть попозже собирался попробовать. Если найду там чего-то интересного, то тоже опишу. При играх с изохроном мне показалось, что на сверхвысоких скоростях может выйти заминка, но пока не ощупаю — боюсь что-то утверждать наверняка. Она может быть, может не быть. Просто смущает необходимость в бесконечном цикле вызывать libusb_handle_events(). Что будет, если на бешеной скорости поток задумается и не сделает этого вовремя? Опять же, надо разобраться, как выводить систему из последнего входа в эту функцию, если устройство долго не шлёт ничего. Так что сначала тщательная проверка, как будет время свободное. Слишком много вопросов, на которые надо ответить перед тем, как начать пользоваться.

Спасибо за ремарку!

Вызывать libusb_handle_events() чётко к моменту завершения каждой транзакции не обязательно, главное — "в среднем" успевать забирать данные в нужном темпе, а одиночные отклонения как раз сгладятся данным механизмом. Делаем submit сразу нескольким транзакциям (количество подбирали экспериментально), драйвер обрабатывает их по очереди и каждой сигналит завершение. Если в какой-то момент не успели поймать очередное завершение до того как произойдут следующие — не беда, следующий вызов handle_events() просигналит их все одно за другим.
Чтобы не "застревать" в ожидании событий есть libusb_handle_events_timeout(), которой можно задавать даже нулевой таймаут, обрабатывать только уже завершённые к моменту вызова транзакции (если есть) и сразу выходить.
Пример (несколько запутанный, но со всеми деталями вроде отмены транзакций): https://github.com/sigrokproject/libsigrok/blob/master/src/hardware/hantek-4032l/protocol.c
У Cypress что-то подобное по смыслу ещё в примерах к FX2 было (AppNote "как выжать 52МБ/с" и РС-часть Screamer demo).

О какая красота!

120046706 Bytes / Sec

Это не из разряда «146%». Как я отмечал в тексте, на выходе ULPI чуть больше шестидесяти мегагерц осциллограф видит. Отсюда и набег.

Большое спасибо!

В целом — классно, а в частности — как исследую все детали, так опишу. Я собирался описывать это в плане большой и красивой кнопки Cancel, отображения процентов полученного буфера и т.п.

Добрый день, я, так получилось, сейчас разбираюсь с fx2lp и дошел до состояния мне нужна программа на ПК для связи с МК. Вы упомянули работу с ioctl напрямую с драйвером cy, не подскажете что это и как именно искать?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации