Андрей Смирнов
Время чтения: ~11 мин.
Просмотров: 93

STM32 и USB. Часть 2. Немного о драйверах и софте.

Установить драйверы автоматически

Бесплатное ПО

Доступные драйверы (1)STM Virtual COM Port

  • Тип драйвера: USBDevice
  • Производитель: libwdi
  • Версия: 6.1.7600.16385 (10 фев 2017)
  • Файл *.inf: stm32_virtual_com_port.inf

<nobr>Windows Vista</nobr>, <nobr>7</nobr>, <nobr>8</nobr>, <nobr>8.1</nobr>, <nobr>10</nobr>

Драйверы для STM Virtual COM Port собраны с официальных сайтов компаний-производителей и других проверенных источников. Официальные пакеты драйверов помогут исправить ошибки и неполадки в работе STM Virtual COM Port (сетевые устройства). Скачать последние версии драйверов на STM Virtual COM Port для компьютеров и ноутбуков на Windows.

Скачать драйвер

Скачать и обновить нужные драйверы автоматически

Версия: 1.1.2.1563 для Windows 7, 8, 10 Бесплатное ПО Скачивая программу, Вы принимаете условия Пользовательского соглашения и Политик конфиденциальности. В комплекте идет опциональное ПО В комплекте идет опциональное ПО

  • Yandex Browser
  • Opera Browser
  • Avast Free Antivirus
  • McAfee Webadvisor
  • Disk-O
  • Yandex Советник
  • Tesla Browser
  • Tesla Start

Связанные статьи:STM32 и USB. Часть 1. Проект для Keil. В прошлой части я рассказал как примерно должен выглядеть проект-заготовка для Keil девайса с USB, дал ссылку на мой проект и рассказал как его настроить под практически любую плату с STM32. В проекте был реализован интерфейс с двумя bulk-ендпойнтами (in и out), с моим «кастомным» протоколом, при помощи которого можно включать, выключать и заставлять светоиоды мигать с нужными временами горения/не горения. Ну и выложил небольшую программу для всего этого:90573a2f02.png Пользователь Vga в комментариях справедливо заметил, что разработка своего драйвера под Windows — задача далеко не тривиальная, и что проще реализовать стандартный класс, например HID, под который драйверы есть. В этой статье я проведу небольшой обзор средств, которыми можно воспользоваться, чтобы сильно упростить себе жизнь. Итак, у нас на повестке следующие варианты: 1) Написать драйвер самому. Задача сложная, неблагодарная, долгая. Тут сразу можно отсылать, например к Windows Driver Foundation. Есть куча примеров, которые можно расковырять и адаптировать под свои задачи. Несомненный плюс этого варианта — решение получится красивое и компактное. Но стоит ли это потраченного времени… Извините, если разочаровал тех, кто полагал, что я опишу именно этот вариант 🙂 2) Реализовать на девайсе один из стандартных классов, например тот же HID. Но давайте предположим что мы вот буквально вчера наконец-то заставили наш девайс определяться по USB как самостоятельное устройство, и все что мы умеем — это читать и писать в ендпойнты. Нам нужно что-то еще проще. 3) Использовать готовые средства. Вот на этом «варианте для начинающих и не только» мы остановимся. Но вначале небольшое отступление. Как Windows опознает наши USB-устройства? В большинстве случаев это «зашитые» в девайс VID (Vendor ID) и PID (Product ID). Есть исключения, например HID и Mass Storage, там Windows опознает класс устройства и подсовывает уже приготовленный драйвер. Если мы воткнем наш девайс в компьютер, система определит его, но, очевидно, будет ругаться на отсутствие драйвера, и предложит выбрать .inf- файл. Именно в этом файле и прописываются, помимо прочего, наши VID и PID, а также путь к драйверу. Есть, конечно, и более хитрые варианты, но мы на них пока останавливаться не будем. Наши VID и PID можно подсмотреть в файле usb_desc.c проекта. И обязательно прочтите комментарий 😉 Итак, встречаем: libusb-win32 и Jungo WinDriver.

Jungo WinDriver

http://www.jungo.com/st/windriver_usb_pci_driver_development_software.html Заметьте, что поддерживает не только USB, но и PCI, и многое другое. Весьма удобная штука. Запускаем Wizard, выбираем по VID-PID наш девайс:5e0068.png Генерим inf-файл, сохраняем, устанавливаем тут же драйвер, и вуаля. Вот они наши два bulk-ендпойнта + управляющий, нулевой ендпойнт:d065e3.png А вот наш девайс определился в диспетчере устройств:79c343.png Но и это не все. Жмем на волшебную кнопку Generate Code:314ed2.png И получаем воистину огромный набор вариантов на любой вкус:704212.png Генерим проект, запускаем. Вот — готовая программа для работы с нашим девайсом:0e3df8.png Можем отправлять данные в ендпойнты и читать их оттуда. Например, отправка пакета на скриншоте согласно моему протоколу зажжет светодиод номер два. (См protocol.txt в проекте Keil) Я сгенерил проект для C# (.NET) и мне он выдал солюшен с двумя проектами: Собственно сама программа и либа для работы с девайсом по USB. В последней есть все необходимое, вплоть до событий подключения-отключения девайса. А вообще если не заморачиваться, то все можно свести к обычному чтению-записи в ендпойнты. Дальше сами справитесь? 😉Ну а теперь поговорим о недостатках. 1) Jungo WinDriver — штука очень уж платная. Кто хочет расстроиться — цены лежат тут. 2) У некоторых USB-девайсов бывает несколько конфигураций. Такое встречается редко, но встречается. WinDriver с такими работать не умеет, а функция смены конфигурации помечена как Not Implemented Yet.

libusb-win32

https://sourceforge.net/apps/trac/libusb-win32 Распаковываем и в папочке bin лежит программка inf-wizard.exe. Тоже визард для генерации инф-файла, а заодно и всех остальных файлов, необходимых для установки драйвера. Запускаем, выбираем наш девайс, сохраняем inf и прочее в отдельную папочку:778fc3.png Ну и сразу инсталлируем.547602.png Теперь, чтобы создать свой проект, необходимо собрать все нужные от libusb файлы в папках lib, include, подсмотреть как работать с устройством, в папке exampes. А работать — проще простого (см bulk.c) Но и этого мне показалось мало. Поскольку меня в свое время подсадили на тяжелый наркотик, именуемый C# + .NET, я стал искать решения, такие же простые, как и Jungo WinDriver. И нашел следующее:

LibUsbDotNet

https://sourceforge.net/projects/libusbdotnet/ Нет, вы только вдумайтесь: .NET-надстройка над библиотекой, портированной из линукса под win32! Конечно, изврат извратом, но мне понравилось. Именно при помощи этой либы я и написал программу из предыдущей статьи. Работать с ендпойнтами так же просто. Ну а дальше реализуем небольшой протокол, пишем-читаем ендпойнты и радуемся мигающим светодиодам 🙂 Только не забываем одну тонкость: весь обмен с USB-девайсом происходит по инициативе хоста. Поэтому, данные не попадут в хост до тех пор пока хост сам не захочет их прочитать. Вот и все.

Итого

Вот, в принципе, все необходимое для того чтобы создать на STM32 примитивный USB-девайс. Весь обмен сводится к чтению и записи в ендпойнты и разбору того, что же туда все-таки пришло и что с этим делать. Лично мне кажется этот вариант проще, чем реализация на девайсе стандатного класса. Как всегда, файлы с проектом находятся тут. Ну а в следующий раз, когда дойдут руки, будем поднимать USB Mass Storage, причем поверх уже сделанного интерфейса для светодиодов, т.е. составное USB-устройство 🙂421b78.jpgРаз у камня есть аппаратный USB, то грех им не пользоваться. Один из способов плюнуть байтом в компьютер и чтобы он при этом не очень обиделся — это организация виртуального COM-порта. Все в железе пробовалось на камне STM32F103ZE, на аналогах тоже должно взлететь.

Забиваем.

Как я уже говорил, пока я сторонник библиотечных решений. Памяти хватает, байтовыцарапыванием заниматься рано. Так что пойдем по легкому пути. STM предоставила нам библиотеку STM32F10x and STM32L1xx USB full-speed device library, версия 3.3.0 Описание к ней: документ CD00158241 — UM0424 User manual Точные названия я привожу на случай если на сайте производителя будет какая-нибудь реорганизация и ссылки станут невалидными. Не забываем дрова виртуального ком-порта. У меня вообще-то оно само все нашлось, но я много чего ставил от STM, может там в комплекте и пришлись. Также нам пригодятся следующие стандарты USB 2.0 SpecificationUSB CDC В составе библиотеки есть пример как раз организации виртуального COM-порта. Правда там он сделан как мост USART-USB, но мы же не боимся трудностей? Цель этой статьи — разобрать приложение, делающее следующее:e94ffc.png

Поджигаем

Собираем проект из нужных нам библиотек: CMSIS, SPD, USB. Дерево проекта прилагаю.1e3b0a.png Как обычно, самое интересное в папочке /src. Вот её-то и будем разбирать.

Неторопливо курим

Начнем с раскуривания библиотеки от STM3becf5.png Эта библиотека предназначена и для connectivity-line устройств (это STM32F105/107), у них не просто USB FS, а USB OTG. Поскольку камней с OTG у меня пока нет, сконцентрируемся на простом USB FS. В примере, который мы взяли за основу, есть куча дефайнов, как раз на случай отличить connectivity-line от других демоплат. Я эти дефайны повырезал, чтобы глаза не мозолили. Cо всей картинки нас интересует High Layer — синенькие квадратики, которые и составляют, собственно, пользовательскую часть библиотеки. Их мы меняем под свои нужды, все остальное остается неизменным. Если заглянуть в папочку /src, то видно, что все эти файлики там и собраны.

Первая затяжка — usb_conf.h

Самые общие настройки библиотеки. Указано сколько у нас будет endpoints (а нам их надо 4 штуки — нулевой для начального конфигурирования устройства, один для команд, один для приема и один для передачи). Также расписаны, какие нам будут нужны коллбэки. Все взаимодействие библиотеки и пользовательской программы построено на обратных вызовах: в случае возникновения какого-либо события вызывается функция с заданным названием. А уже содержание этой функции — проблема разработчика. Нам будет нужен SOF_CALLBACK – сигнал начала фрейма (Start Of Frame). По нему будем выплевывать то, что накопилось в буфере передачи. Также резервируем еще два коллбэка — на прием и передачу. По приему символа будем мигать светодиодами, чтобы уж как-нибудь задействовать канал приема. Упс, кончился файл. Короткая получилась затяжка. Файл берем из примера, ничего не меняем.

Вторая затяжка — usb_desc.h / usb_desc.c

В этих файлах находятся дескрипторы устройства и эндпоинтов. Информация по стандартным дескрипторам есть в стандарте USB, в разделе 9.6 Standard USB Descriptor Definitions Специфические дескрипторы описаны в USB CDC, раздел 5 (так и называется Descriptors), Эти все тонны текста в стандартах для того, чтобы USB стала действительно Universal. Поэтому тщательно выведена классификация устройств и интерфейсов — чтобы глянув на дескриптор хост сразу понял, что с этим делать. Особо подробно разбирать смысла не вижу — это не характерно для STM32, это общая боль разработчиков USB устройств. Файл берем из примеров, ничего не меняем.

Продолжение дескрипторов — usb_prop.h / usb_prop.c

В этих файлах описана таблица реакции на запросы. Все запросы к устройству пронумерованы и стандартизованы. В этих файлах определяется массивы функций Device_Property, User_Standard_Requests и просто массивы String_Descriptor, например. Это все используется ядром. Когда в устройство приходит определенный запрос, например «Выдай мне дескриптор устройства», то ядро посмотрит в таблице, какая функция обрабатывает этот запрос, вызовет эту функцию, а оно уже отработает: Опять же, берем файл из примеров.

Прерываемся — usb_istr.h / usb_istr.c

Тоже два коротеньких файла. В них находится то, что надо вызывать при приходе прерывания от USB. Поскольку прерывание одно, то по значениям флагов определяется событие и вызывается соответствующий коллбэк. Прерывание будет настраиваться в файле hw_config.c, обработчик выглядит очень просто: void USB_LP_CAN1_RX0_IRQHandler(void) { USB_Istr(); } его можно разместить в файлах stm32f10x_it.*, а в данном проекте, чтобы не растекаться мысью по древу, я его включил в файл main.c И тут особо ничего не меняем, все как в примере.

Питание — usb_pwr.h / usb_pwr.c

Здесь все, что касается питания. По стандарту, устройство может быть переведено в режим спячки, тогда, если оно питается от порта, нужно позаботиться об отключении жрущей периферии. Поскольку у нас плата питается отдельно, то особого смысла в управлении питанием нет. Просто устройство формально переводится в состояние SUSPENDED. Ничего не меняем, файл из примеров.

Коллбэки — usb_endp.c

Этот файл я переписал, поскольку у нас не будет работы с USART, как это было в примере. Приведу код с комментариями:

Работа с железом — hw_config.h / hw_config.c

В этом файле собраны функции инициализации периферии, прерываний, функции управления светодиодами и работы с буфером отправки. USB-порт и подтяжки на моей плате сделаны по такой схеме:46d843.png И USB_EN заведен на пин PF11. Значит надо не забыть его проинициализировать и дернуть вовремя. По сравнению с примером, выкинуты функции инициализации и работы с USART, добавлена функция мигания светодиодом. По приему символов ‘A’, ‘B’, ‘C’, ‘D’ – зажигаются соответствующие светодиоды, ‘a’, ‘b’, ‘c’, ‘d’ – гасятся. ‘1’ и ‘0’ — соответственно зажигают и гасят все светодиоды. Ну и все, что будет передано функции USB_Send_Data() попадает в буфер, а затем и через USB – в комп. Уфф. С USB вроде закончили. Теперь в головной программе можно просто вызывать USB_Send_Data() и посимвольно передавать данные в комп. Если мы на этом остановимся, то размер кода будет порядка 11 кБ: Более двух килобайт bss – это буферы приема и передачи. Понятное дело, их можно уменьшить.

Выдыхаем — printf()

Но мы же хотим, чтобы вывод функции printf() перенаправлялся в наш свежесозданный COM-порт. Подключаем и офигеваем от количества ошибок линковки: А тут все просто — стандартная библиотека ввода-вывода подразумевает работу с файлами, но в больших системах есть ОС, которая собственно и занимается организацией файлов для программ пользователя. А поскольку у нас нет никакой ОС, то библиотека вполне справедливо недоумевает «А что же мне делать-то?» Вот, чтобы это обойти, в проект включается файл newlib_stubs.c В нем находятся функции-заглушки ко всем вышеперечисленным ошибкам. Но и кроме этого, есть одна функция, которую нам и надо переписать, чтобы весь вывод шел в USB: Видим, что как раз и вызывается наша функция USB_Send_Data() Все, компилим, собираем, запускаем. Архив с проектом прилагаю — это на случай, если кто не заметит маленькие буковки внизу 🙂Используемые источники:

  • https://ru.drvhub.net/devices/network/stm/virtual-com-port-10
  • http://we.easyelectronics.ru/stm32/stm32-i-usb-chast-2-nemnogo-o-drayverah-i-softe.html
  • http://we.easyelectronics.ru/stm32/stm32-organizaciya-virtualnogo-com-porta.html

Рейтинг автора
5
Подборку подготовил
Андрей Ульянов
Наш эксперт
Написано статей
168
Ссылка на основную публикацию
Похожие публикации
Тимофей Белов
Консультант сайта
Здравствуйте. Если у вас остались вопросы, вы можете можете задать их мне.