Ftdi події підключення і відключення usb-пристрої, pc, programming

Багато програм, що працюють з пристроєм USB. втрачають працездатність при випадковій втраті зв'язку. Наприклад, якщо неякісне підключення (поганий контакт в роз'ємі miniUSB або microUSB, що досить часто трапляється), або коли пристрій був випадково перепідключитися в порт USB, доводиться перезапускати програму ПО хоста. Щоб коректно обробляти такі ситуації в програмі, необхідно програмно детектувати події підключення і відключення пристрою USB, щоб можна було здійснити адекватні дії - повторна ініціалізація зв'язку з пристроєм, настройка параметрів і т. П. Тут наведено переклад апноута FTDI AN_152 [1], як раз присвяченого цій важливій темі.

У цій статті показано, як програмно детектувати підключення пристроїв USB в порт хоста і їх відключення, коли ПО хоста працює під управлінням Windows. Приклад ПО хоста називається D2XXNotify, і його можна вільно скачати з сайту FTDI в розділі прикладів програм на C ++ [2]. Додаток ПО хоста прослуховує повідомлення системи WM_DEVICECHANGE, яке активізується, обробляється і відправляється до вікна програми, коли користувач щось підключає до комп'ютера або відключає, наприклад вставляє в порт USB якийсь пристрій (зокрема пристрій USB на чіпі FTDI). Будь-яке програмне забезпечення, що описується в цьому документі, наведено тільки для інформації, і ніяк не підтримується компанією FTDI.

[Як детектувати події установки і видалення пристрою USB]

Операційна система Windows розсилає широкомовні оповіщення (broadcasts basic notifications message) будь-якого додатка, що створив вікно верхнього рівня (зараз нас цікавить додаток ПО хоста USB, яке управляє пристроями USB на чіпах FTDI, хоча це може бути будь-який додаток, що працює з апаратурою), для цього додаток повинен обробити повідомлення WM_DEVICECHANGE. Під вікном верхнього рівня додатки (top-level window) мається на увазі вікно, яке може бути оброблено стандартним менеджером вікон Windows: наприклад вікно може бути незалежно від інших вікон переміщатися користувачем по робочому столу, і у вікна користувач може змінювати розміри.

Повідомлення WM_DEVICECHANGE сповіщає додаток про подію зміни конфігурації апаратури серед пристроїв, підключених і встановлених на комп'ютері. Якщо програма не має вікна верхнього рівня, або якщо воно вимагає оповіщення про інші зміни серед пристроїв, то програма може використовувати функцію Win32 Application Programming interface (API, інтерфейс програмування системи) RegisterDeviceNotification. яка реєструє додаток в системі для прийому подій оповіщення, пов'язаних з пристроями (device notification events). Для цієї функції буде надано хендл (handle), який вказує на структуру DEV_BROADCAST_DEVICEINTERFACE (в ній міститься вся інформація про клас пристрою) і прапор, який може бути DEVICE_NOTIFY_WINDOW_HANDLE (якщо це віконне додаток) або DEVICE_NOTIFY_SERVICE_HANDLE (якщо це сервіс системи). Функція Win32 API function UnRegisterDeviceNotification закриває вказаний хендл, який був повернутий функцією RegisterDeviceNotification. Подробиці див. На сайті Microsoft [3].

Наступний приклад коду на мові C показує, як функція RegisterDeviceNotification реєструє додаток в системі, щоб воно отримувало оповіщення про пристрої.

Функція в параметрах приймає хендл GetSafeHwnd (), прапор DEVICE_NOTIFY_WINDOW_HANDLE і покажчик на структуру даних DEV_BROADCAST_DEVICEINTERFACE. Прапор DEVICE_NOTIFY_WINDOW_HANDLE вказує, що викликає код відноситься до вікна додатка, і структура даних DEV_BROADCAST_DEVICEINTERFACE задає розмір цієї структури, тип пристрою DBT_DEVTYP_DEVICEINTERFACE, ім'я пристроїв і унікальний ідентифікатор інтерфейсу пристрою (device Globally Unique Identifier, GUID). Список (масив) GuidInterfaceList буде розшифрований в наступній секції.

Примітка: значення структури даних DEV_BROADCAST_DEVICEINTERFACE повинні бути відредаговані відповідно до вимог Вашого застосування. Щоб використовувати наведений вище код, переконайтеся, що заголовок Dbt.h підключений до додатка. Додаткову інформацію див. На сайті Microsoft [3].

[Device Globally Unique Identifier (GUID)]

Ідентифікатор device interface GUID вказує приватний інтерфейс вводу / виводу (particular input / output interface). Мається на увазі, що кожен екземпляр device interface GUID підтримує один і той же базовий набір входів / виходів. Ідентифікатор device interface GUID - це те, що драйвер зареєструє і буде дозволяти або забороняти, базуючись на стані PnP. У попередньому розділі приклад коду показує, як в циклі for реєструється кілька повідомлень для кожного GUID.

Наступний код дає список GUID для класів інтерфейсу пристроїв.

[Обробка повідомлення WM_DEVICECHANGE на C ++]

При будь-якій зміні у стані пристрою (наприклад, пристрій було підключено або було вилучено) ця подія буде детектуватиметься і з додатком буде відправлено повідомлення WM_DEVICECHANGE, і структура повідомлення передасть значення події, що сталася в параметрі повідомлення WParam. Поле wParam може отримати різні значення з файлу заголовка Dbt.h. Наприклад, DBT_DEVICEARRIVAL і DBT_DEVICEREMOVALCOMPLETE показують відповідно підключення і вилучення пристрою. Подробиці див. На сайті Microsoft [4].

Ftdi події підключення і відключення usb-пристрої, pc, programming

Мал. 2.1. Алгоритм обробки повідомлення WM_DeviceChange.

Приклад коду нижче показує, як в додатку може бути оброблено повідомлення WM_DEVICECHANGE, коли це повідомлення було доставлене додатком.

Програма D2XXNotify надає користувачеві інтерфейс, в якому детектируются установка або вилучення пристроїв USB на комп'ютері. Вихідний код цього додатка доступний на сайті FTDI [2].

[Запуск виконуваного файлу]

Готовий виконуваний файл програми D2XXNotify.exe можна завантажити з сайту FTDI [2] в складі архіву D2XXNotify.zip (в цьому ж архіві міститься також і вихідний код програми). Розпакуйте архів за допомогою будь-якого архіватора, наприклад WinZIP або WinRAR. Подвійним клацанням в Провіднику запустіть додаток D2XXNotify.exe. З'явиться наступне вікно:

Ftdi події підключення і відключення usb-пристрої, pc, programming

Мал. 3.1. Запуск програми D2XXNotify з двійкового виконуваного файлу.

Коли пристрій USB підключається до порту USB комп'ютера, то буде відправлено подія оповіщення інтерфейсу пристрою USB, і додаток отримає повідомлення WM_DEVICECHANGE. Додаток викличе відповідну функцію, зазначену в карті повідомлень (див. Нижче секцію статті "Message Map"), і у вікні з'явиться інформація про підключення, як це показано на скріншоті 3.2.

Ftdi події підключення і відключення usb-пристрої, pc, programming

Мал. 3.2. Додаток отримало повідомлення DBT_DEVICEARRIVAL (було підключено пристрій USB).

На рис. 3.2 видно, що додаток D2XXNotify відобразило повідомлення DBT_DEVNODES_CHANGED, DBT_DEVICEARRIVAL і PID і VID пристрою, коли воно було додано в систему (операційна система відправляє події пристрою DBT_DEVNODES_CHANGED і DBT_DEVICEARRIVAL).

Коли пристрій USB витягується з комп'ютера, буде відправлено оповіщення події інтерфейсу пристрою USB, і додаток отримає повідомлення WM_DEVICECHANGE. На екрані з'явиться текст, як це видно в прикладі на скріншоті 3.3.

Ftdi події підключення і відключення usb-пристрої, pc, programming

Мал. 3.3. Додаток отримало повідомлення DBT_DEVICECOMPLETE (пристрій USB від'єднано).

На рис. 3.3 видно, що додаток D2XXNotify відобразило повідомлення DBT_DEVNODES_CHANGED, DBT_DEVICEREMOVECOMPLETE і PID і VID пристрою, коли воно було вилучено з системи (операційна система відправляє події пристрою DBT_DEVNODES_CHANGED і DBT_ DEVICEREMOVECOMPLETE).

Додаток також доступний із середовища розробки Microsoft Visual Studio. Для цього запустіть Visual Studio, відкрийте файл d2xxnotify.sln з розпакованого архіву, виконайте стандартні операції по очищенню проекту (Clean Solution) і збірці (Rebuild Solution). Після цього можна запустити додаток (меню Debug -> Start Debugging або Start Without Debugging).

Ftdi події підключення і відключення usb-пристрої, pc, programming

Ftdi події підключення і відключення usb-пристрої, pc, programming

Ftdi події підключення і відключення usb-пристрої, pc, programming

Message Map - спосіб обробки повідомлень програми, визначений в бібліотеці класів Microsoft Foundation Class (MFC). Це таблиця, в якій відображена взаємозв'язок між подіями і відповідними функціями. Коли вікно приймає повідомлення, MFC сканує message map вікна, щоб визначити - чи є обробник (handler) для цієї події, який потрібно викликати. Наступний приклад коду на мові C ++ показує, як message map може використовуватися в додатку.

[Обробка повідомлення WM_DEVICECHANGE на C #]

Приклад детектування підключення / відключення пристрою побудований на основі перевизначення в додатку процедури WndProc. В процедуру передається параметр Message, поле Msg якого обробляється на предмет появи повідомлення WM_DEVICECHANGE. Якщо отримано таке повідомлення, то поле wParam декодируется, щоб зрозуміти до якого типу належить повідомлення. Для типу повідомлення DBT_DEVICEARRIVAL проводиться додаткове декодування, для чого поле LParam повідомлення прив'язується до відповідної інформаційної структурі.

Ftdi події підключення і відключення usb-пристрої, pc, programming

Зверніть увагу, що в цих прикладах коду зовсім використовувалася бібліотека D2XX компанії FTDI - обробка подій підключення і відключення пристроїв здійснюється на основі системи повідомлень Windows API.

Тексти програм і виконувані exe-файли тестових програм можна скачати за посиланням [6].

1. How To Detect The Connection And Removal Of USB Devices On A System site: ftdichip.com.
2. Visual C ++ Examples site: ftdichip.com.
3. RegisterDeviceNotification function site: msdn.microsoft.com.
4. WM_DEVICECHANGE message site: msdn.microsoft.com.
5. Клас-обгортка для AVR-USB-MEGA16 з підтримкою подій.
6. 150612D2XXNotify.zip - вихідний код проектів C ++ і C # для Visual Studio.