Основы интерфейса USB.

Сегодняшняя статья будет посвящена, как уже видно из названия, обсуждению основ интерфейса USB. Рассмотрим основные понятия, структуру интерфейса, разберемся, как происходит передача данных, а в ближайшем будущем реализуем все это на практике 😉 Короче, приступаем!

Интерфейс USB

Существует ряд различных спецификаций USB. Началось все с USB 1.0 и USB 1.1, затем интерфейс эволюционировал в USB 2.0, относительно недавно появилась окончательная спецификация USB 3.0. Но на данный момент наиболее распространенной является реализация USB 2.0.

Ну и для начала основные моменты и характеристики. USB 2.0 поддерживает три режима работы:

  • High Speed — до 480 МБ/с
  • Full Speed — до 12 МБ/с
  • Low Speed — до 1.5 МБ/с

Командует на шине USB хост (например, ПК), к которому можно подключить до 127 различных устройств. Если этого мало, то нужно добавить еще один хост. Причем немаловажно, что устройство не может само послать/принять данные хосту/от хоста, необходимо, чтобы хост сам обратился к устройству.

Почти во всех статьях про USB, которые я видел используется термин «конечная точка«, но о том, что это такое обычно написано довольно туманно. Так вот, конечная точка — это часть устройства USB, имеющая свой уникальный идентификатор. Каждое устройство USB может иметь несколько конечных точек. По большому счету — конечная точка — это всего лишь область памяти USB устройства, в которой могут храниться какие-либо данные (буфер данных). И в итоге мы получаем вот что — каждое устройство имеет свой уникальный адрес на шине USB, и при этом каждая конечная точка этого устройства имеет свой номер. Вот так вот )

Давайте немного отвлечемся и поговорим о «железной части» интерфейса.

Существуют два типа коннекторов — Type A и Type B.

Коннекторы USB

Как уже понятно из рисунка Type A всегда обращен к хосту. Именно такие разъемы мы видим на компьютерах и ноутбуках. Коннекторы Type B всегда относятся к подключаемым USB-устройствам. Кабель USB состоит из 4 проводов разных цветов. Ну, собственно, красный — это питание (+5 В), черный — земля, белый и зеленый предназначены для передачи данных.

Помимо изображенных на рисунке, существуют также другие варианты исполнения USB-коннекторов, например, mini-USB и другие, ну это вы и так знаете 😉

Наверно стоит немного коснуться способа передачи данных, но углубляться в это не будем ) Итак, при передаче данных по шине USB используется принцип кодирования NRZI (без возврата к нулю с инверсией). Для передачи логической «1» необходимо повысить уровень линии D+ выше +2.8 В, а уровень линии D- надо понизить ниже +0.3 В. Для передачи нуля ситуация противоположная — (D- > 2.8 В) и (D+ < 0.3 В).

Отдельно стоит обсудить питание устройств USB. И тут также возможно несколько вариантов.

Во-первых устройства могут питаться от шины, тогда их можно разделить на два класса:

  • Low-power
  • High-power

Разница тут заключается в том, что low-power устройства не могут потреблять больше, чем 100 мА. А устройства high-power должны потреблять не более 100 мА лишь на этапе конфигурации. После того, как они сконфигурированы хостом их потребление может составлять до 500 мА.

Кроме того, устройства могут иметь свой собственный источник питания. В этом случае они могут получать до 100 мА от шины, а все остальное забирать у своего источника )

С этим вроде бы все, давайте потихоньку переходить к структуре передаваемых данных. Все-таки это представляет для нас наибольший интерес 😉

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

Интерфейс USB

Каждый кадр включает в себя пакет SOF (Start Of Frame), затем следуют транзакции для разных конечных точек, ну и завершается все это пакетом EOF (End Of Frame). Если говорить совсем точно, то EOF — это не совсем пакет в привычном понимании этого слова — это интервал времени, в течение которого обмен данными запрещен.

Каждая транзакция имеет следующий вид:

Структура транзакции

Первый пакет (его называют Token пакет) содержит в себе информацию об адресе устройства USB, а также о номере конечной точки, которой предназначена эта транзакция. Кроме того, в этом пакете хранится информация о типе транзакции (какие бывают типы мы еще обсудим, но чуть позже =) ). Data пакет — с ним все понятно, это данные, которые передают хост, либо конечная точка (зависит от типа транзакции). Последний пакет — Status — предназначен для проверки успешности получения данных.

Уже очень много раз прозвучало слово «пакет» применительно к интерфейсу USB, так что пора разобраться что он из себя представляет. Начнем с пакета Token:

Пакет Token

Пакеты Token бывают трех типов:

  • In
  • Out
  • Setup
  • Start Of Frame

Пакет In говорит нашему USB-устройству, что хост готов принять от него информацию. Пакет Out, напротив, сигнализирует о готовности и желании хоста поделиться информацией. Пакет Setup нужен для использования управляющих передач. Ну а пакет Start Of Frame используется для того, чтобы инициировать начало кадра.

Вот к чему я это рассказал..) В зависимости от типа пакета значение поля PID в Token пакете может принимать следующие значения:

  • Token пакет типа OUT — PID = 0001
  • Token пакет типа IN — PID = 1001
  • Token пакет типа SETUP — PID = 1101
  • Token пакет типа SOF — PID = 0101

Переходим к следующей составной части пакета Token — поля Address и Endpoint — в них содержатся адрес USB устройства и номер конечной точки, которой предназначена транзакция.

Ну и поле CRC — это контрольная сумма, с этим понятно.

Тут есть еще один важный момент. PID включает в себя 4 бита, но при передаче они дополняются еще 4-мя битами, которые получаются путем инвертирования первых 4-ых бит.

Итак, на очереди Data пакет — то есть пакет данных.

Data пакет

Тут все в принципе так же, как и в пакете Token, только вместо адреса устройства и номера конечной точки здесь у нас передаваемые данные.

Осталось нам рассмотреть Status пакеты и пакеты SOF:

USB структура данных

Тут PID может принимать всего лишь два значения:

  • Пакет принят корректно — PID = 0010
  • Ошибка при приеме пакета — PID = 1010

И, наконец, Start Of Frame пакеты:

Пакет SOF

Здесь видим новое поле Frame — оно содержит в себе номер передаваемого кадра.

Давайте в качестве примера рассмотрим процесс записи данных в USB-устройство. То есть рассмотрим пример структуры кадра записи.

Кадр, как вы помните состоит из транзакций и  имеет следующий вид:

Структура кадра USB

Что представляют из себя все эти транзакции? Сейчас разберемся! Транзакция SETUP:

USB, структура транзакции

Транзакция OUT:

Транзакция OUT

Аналогично при чтении данных из USB-устройства кадр выглядит так:

USB чтение данных

Транзакцию SETUP мы уже видели, посмотрим на транзакцию IN 😉

Транзакция IN

Как видите, все эти транзакции имеют такую структуру, как мы обсуждали выше )

В общем, думаю достаточно на сегодня 😉 Довольно-таки длинная статья получилась, надеюсь в ближайшее время попробуем реализовать интерфейс USB на практике!

Понравилась статья? Поделись с друзьями!

Основы интерфейса USB.: 9 комментариев
  1. Добрый вечер! Отличная статья, спасибо! У меня вопрос, а почему PID одинаковые?
    В зависимости от типа пакета значение поля PID в Token пакете может принимать следующиЕ значения:
    Token пакет типа OUT — PID = 0001

    Token пакет типа SETUP — PID = 0001

  2. Статьи просто классные! Спасибо!
    Возник вопросик по поводу поля SYNC. Что оно из себя представляет не могу найти нигде. Буду очень благодарен за ответ.

  3. Приветствую. Тут было упоминание о CRC.
    1) Означает ли это, что если проверка контрольной суммы не пройдет успешно, то устройство, принимающее данные просто их проигнорирует и мы в отладчике увидим отсутствие изменений? Как будто ничего и не приходило. Как тогда организовывать обмен правильно?
    2) Каков полином для этого CRC? Но это так, скорее вопрос из любопытства

  4. Здравствуйте, уважаемый Aveal, я не уверен, но кажется, что в вашей статье есть некоторая неточность. Вы написали: «ну и завершается все это пакетом EOF (End Of Frame).». Но такого пакета не существует, EOF — это просто временная пауза, интервал времени, в течении, которого на линии не должно происходить никаких обменов. Насколько мне известно, крайний интервал времени, когда должна завершиться транзакция, это время между флагами EOF1 и EOF2, которые выставляются за 32(EOF1) и 10(EOF2) битовых интервала, до следующего пакета SOF. Если хост продолжает пихать данные после поднятия флага EOF2, то мк, просто обрубит порт, и как следствие придется предпринимать соответствующие меры.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *