інтерфейс usb
З'явилося трохи вільного часу, і я вирішив написати невелику «позапланову» статтю.
Отже, з попередньої статті, ми знаємо, що для обміну даними використовуються якісь віртуальні канали - «кінцеві точки». Давайте розглянемо, як відбувається обмін.
Обмін даними по USB
Розглянемо, як відбувається обмін даними.
Ініціатором обміну завжди виступає хост. Пристрій не може почати передачу даних за власною ініціативою. Хост черзі (ЕМНІП, з інтервалом в 1 мс, але «низькошвидкісні» пристрою можуть опрашиваться не кожен раз, а, наприклад, раз за 10 циклів опитування) опитує всі подученний пристрою. Кожен раз, при опитуванні, пристрій може отримати дані від хоста і відправити дані хосту.
Сам обмін здійснюється пакетами. Стандартом передбачено кілька типів пакетів. «Побайтное» ми поки розбирати пакети не будемо, але торкнемося цього питання у практичній частині.
Справа в тому, що частина роботи по формуванню та передачі пакетів (наприклад, питання синхронізації, розрахунок контрольних сум і т. Д.) Візьме на себе USB периферія МК. Для тих, хто хоче відразу заглибитися в біти і байти можу порекомендувати ознайомитися з розділом 8 офіційної специфікації USB 2.0
Поки нам досить знати, що існують «пакети даних» та кілька типів «службових пакетів».
USB і Plug and Play
Давайте розглянемо, що з нашим пристроєм буде відбуватися далі, після того як хост визначив підключення нового пристрою і готовий почати обмін даними. Нам потрібно ненадовго піднятися на «високий» рівень - рівень ОС.
Справа в тому, що в стандарт USB підтримує концепцію Plug and Play (підключи і грай). Дана концепція має на увазі, що користувачеві досить «увіткнути» пристрій до відповідного порт ПК. Далі ОС автоматично визначить тип підключеного пристрою, знайде відповідний для даного пристрою драйвер, сконфигурирует пристрій і т. Д. (Правда, це звичайно в ідеалі :))
Для того щоб вся ця краса працювала, стандартом USB передбачені деякі загальні вимоги для всіх пристроїв:
1. Кожен пристрій містить «власне опис» (дескриптор пристрою).
2. Є якийсь, загальний для всіх USB пристроїв, механізм який дозволяє ОС прочитати дескриптор пристрою для того, щоб ідентифікувати пристрій, дізнатися його характеристики.
Даними речами (читання дескриптора пристрою, ідентифікація пристроїв) займається якась служба ОС, яка відповідає за базову підтримку USB.
Після того як пристрій буде ідентифіковано і проведена певна первинна ініціалізація, дана служба передасть управління пристроєм драйверу, який «закріплений» за даним типом пристроїв (або конкретно за цим пристроєм).
Що буде, якщо служба не зможе знайти «відповідний» драйвер для даного пристрою знають всі :)
Тепер повертаємося на наш «низький» рівень.
Початок роботи з пристроєм. Стандартні заріс.
На практиці, для читання дескриптора пристрою і первинної ініціалізації використовуються та сама «нульова кінцева точка». Є кілька передбачених стандартом запитів (Standard Device Requests), які повинні оброблятися всіма USB пристроями. Поки приведу кілька прикладів таких запитів:
GET_DESCRIPTOR - запит на отримання дескриптора пристрою. Даний запит містить додаткову інформацію про те, який саме дескриптор має повернути (в пристрої «зберігається» кілька різних дескрипторів, але про це пізніше).
GET_CONFIGURATION - запит на отримання поточної конфігурації пристрою.
Потрібно розуміти, що запит - це не більше ніж стандартизована структура даних, яка містить код запиту (bRequest) і додаткові дані. Відповіді на кожен із запитів теж, природно, стандартизовані.
Крім стандартних запитів, які пристрій «зобов'язана» підтримувати, можна визначити «свої» запити, специфічні для конкретного пристрою (класу пристроїв).
Детально з усією «кухнею» запитів і відповідей ми познайомимося в «практичної» частини.
Заодно, для того щоб показати як виглядає той самий дескриптор пристрою приведу приклад:
Поки це просто ілюстрація того, як виглядає дескриптор, вникати в значення полів не варто, цим ми займемося в наступній статті.
На цьому, пропоную зав'язувати з голою теорією і поступово переходити до практики. У наступній статті почнемо потихеньку писати код.