Stm32 і usb

У минулій частині я розповів як приблизно має виглядати проект-заготовка для Keil девайса з USB, дав посилання на мій проект і розповів як його налаштувати під практично будь-яку плату з STM32.

У проекті був реалізований інтерфейс з двома bulk-ендпойнтамі (in і out), з моїм «кастомними» протоколом, за допомогою якого можна включати, вимикати і змушувати светоіоди блимати з потрібними часом горіння / НЕ горіння.

Ну і виклав невелику програму для всього цього:

Stm32 і usb

У цій статті я проведу невеликий огляд засобів, якими можна скористатися, щоб сильно спростити собі життя.

Отже, у нас на порядку наступні варіанти:

1) Написати драйвер самому. Завдання складне, невдячна, довга. Тут відразу можна відсилати, наприклад до Windows Driver Foundation. Є купа прикладів, які можна розколупати і адаптувати під свої завдання.
Безсумнівний плюс цього варіанту - рішення вийде гарне і компактне. Але чи варто це витраченого часу ...
Вибачте, якщо розчарував тих, хто вважав, що я опишу саме цей варіант :)

3) Використовувати готові засоби. Ось на цьому «варіанті для початківців і не тільки» ми зупинимося.

Але спочатку невеликий відступ.

Як Windows пізнає наші USB-пристрої?
У більшості випадків це «зашиті» в девайс VID (Vendor ID) і PID (Product ID). Є винятки, наприклад HID і Mass Storage, там Windows пізнає клас пристрою і підсовує вже приготований драйвер.

Якщо ми застромимо наш девайс в комп'ютер, система визначить його, але, очевидно, буде лаятися на відсутність драйвера, і запропонує вибрати .inf- файл.
Саме в цьому файлі і прописуються, крім іншого, наші VID і PID, а також шлях до драйвера.

Отже, зустрічаємо: libusb-win32 і Jungo WinDriver.

Jungo WinDriver

Вельми зручна штука.
Запускаємо Wizard, вибираємо по VID-PID наш девайс:

Stm32 і usb

Генерітся inf-файл, зберігаємо, встановлюємо тут же драйвер, і вуаля. Ось вони наші два bulk-ендпойнта + керуючий, нульовий ендпойнт:

Stm32 і usb

А ось наш девайс визначився в диспетчері пристроїв:

Stm32 і usb

Але і це не все. Тиснемо на чарівну кнопку Generate Code:

Stm32 і usb

І отримуємо воістину величезний набір варіантів на будь-який смак:

Stm32 і usb

Я згенерувати проект для C # (.NET) і мені він видав СОЛЮШЕН з двома проектами: Власне сама програма і Ліба для роботи з девайсом по USB. В останній є все необхідне, аж до подій підключення-відключення девайса. А взагалі якщо не морочитися, то все можна звести до звичайного читання-запису в ендпойнти.
Далі самі впораєтеся? ;-)

Ну а тепер поговоримо про недоліки.
1) Jungo WinDriver - штука дуже вже платна. Хто хоче почати турбуватися - ціни лежать тут.
2) У деяких USB-девайсів буває кілька конфігурацій. Таке зустрічається рідко, але зустрічається.
WinDriver з такими працювати не вміє, а функція зміни конфігурації позначена як Not Implemented Yet.

libusb-win32

Розпаковуємо і в таткові bin лежить програмка inf-wizard.exe. Теж візард для генерації інф-файлу, а заодно і всіх інших файлів, необхідних для установки драйвера.
Запускаємо, вибираємо наш девайс, зберігаємо inf та інше в окрему папочку:

Stm32 і usb

Ну і відразу інсталюємо.

Stm32 і usb

Тепер, щоб створити свій проект, необхідно зібрати всі потрібні від libusb файли в папках lib, include, підглянути як працювати з пристроєм, в папці exampes. А працювати - простіше простого (див bulk.c)


Але і цього мені здалося мало. Оскільки мене свого часу підсадили на важкий наркотик, іменований C # + .NET, я став шукати рішення, такі ж прості, як і Jungo WinDriver.
І знайшов наступне:

LibUsbDotNet

Саме за допомогою цієї ліби я і написав програму з попередньої статті. Працювати з ендпойнтамі так само просто.


Ну а далі реалізуємо невеликий протокол, пишем-читаємо ендпойнти і радіємо миготливим светодиодам :)
Тільки не забуваємо одну тонкість: весь обмін з USB-девайсом відбувається з ініціативи хоста. Тому, дані не потраплять в хост до тих пір поки хост сам не захоче їх прочитати.
От і все.

Ось, в принципі, все необхідне для того щоб створити на STM32 примітивний USB-девайс. Весь обмін зводиться до читання і записи в ендпойнти і розбору того, що ж туди все-таки прийшло і що з цим робити.
Особисто мені здається цей варіант простіше, ніж реалізація на девайсе стандатного класу.

Як завжди, файли з проектом знаходяться тут.

Ну а в наступний раз, коли дійдуть руки, будемо піднімати USB Mass Storage, причому поверх вже зробленого інтерфейсу для світлодіодів, тобто складене USB-пристрій :)

LibUsb штука хороша, але стандартні класи теж не погані. Наприклад, клас CDC бачиться в системі як віртуальний КОМ порт, що не може не радувати, а реалізується дуже просто. Все-таки робота на будь-якій системі без установки своїх драйверів багато коштує.

Ну да :) Тільки CDC-клас все одно зажадає inf-файлу, а також своїх VID-PID. Ну лінукс не береться до уваги.

Взагалі завдання стояло така: організувати USB-обмін максимально швидко і просто, читанням і записом в ендпойнти. А реалізація навіть CDC це вже хоч якийсь, але поглиблення :)

За статті спасибі, цікаво і пізнавально. Зараз помаленьку теж колупаю USB. Помаленьку - тому, що поки я не бачу особливого сенсу креативити свої USB-утройства, бо є FT232. VCP - наше все. )

ft232 коштує приблизно стільки ж, скільки stm32f103. Є сенс. )