link980 link981 link982 link983 link984 link985 link986 link987 link988 link989 link990 link991 link992 link993 link994 link995 link996 link997 link998 link999 link1000 link1001 link1002 link1003 link1004 link1005 link1006 link1007 link1008 link1009 link1010 link1011 link1012 link1013 link1014 link1015 link1016 link1017 link1018 link1019 link1020 link1021 link1022 link1023 link1024 link1025 link1026 link1027 link1028 link1029 link1030 link1031 link1032 link1033 link1034 link1035 link1036 link1037 link1038 link1039 link1040 link1041 link1042 link1043 link1044 link1045 link1046 link1047 link1048 link1049 link1050 link1051 link1052 link1053 link1054 link1055 link1056 link1057 link1058 link1059 link1060 link1061 link1062 link1063 link1064 link1065 link1066 link1067 link1068 link1069 link1070 link1071 link1072 link1073 link1074 link1075 link1076 link1077 link1078 link1079 link1080 link1081 link1082 link1083 link1084 link1085 link1086 link1087 link1088 link1089 link1090 link1091 link1092 link1093 link1094 link1095 link1096 link1097 link1098 link1099 link1100 link1101 link1102 link1103 link1104 link1105 link1106 link1107 link1108 link1109 link1110 link1111 link1112 link1113 link1114 link1115 link1116 link1117

PersCom — Компьютерная Энциклопедия Компьютерная Энциклопедия

USB

USB

Питание от шины

Шина USB обеспечивает устройства питанием по линии Vbus с номинальным напряжением 5 В относительно линии GND. Питание подается на нисходящие порты хабов; устройства-функции могут только потреблять питание (как и хаб по своему восходящему порту). Естественно, устройства могут пользоваться и собственным питанием. Мощность питания от шины выделяют единицами по 100 мА, устройству шина может предоставить максимум 5 единиц (0,5А). При начальном подключении (до конфигурирования) устройство может потреблять не более 1 единицы (100 мА). Порт, обеспечивающий 5 единиц, называют мощным (high-power port); маломощный порт (low-power port) обеспечивает лишь 1 единицу. По отношению к питанию от шины различают следующие типы устройств:

  • корневой хаб, получающий питание вместе с хост-контроллером. При питании от внешнего источника хаб должен иметь мощные порты; при автономном (от батарей) питании порты могут быть как мощными, так и маломощными;
  • хаб, питающийся от шины (Bus-powered hub), может иметь только маломощные порты (и не более четырех, поскольку одну единицу мощности потребляет его контроллер). Питание на нисходящие порты этот хаб подает только после того, как будет сконфигурирован (поскольку до того он может потреблять лишь 1 единицу);
  • хабы с собственным питанием (Self-powered hub) могут потреблять от шины лишь одну единицу. На свои нисходящие порты он подает питание от другого источника; эти порты могут быть как мощными, так и маломощными (у хаба с батарейным питанием);
  • маломощные устройства с питанием от шины (Low-power bus-powered functions) могут потреблять не более одной единицы;
  • мощные устройства с питанием от шины (High-power bus-powered functions) могут потреблять до пяти единиц;
  • устройства с собственным питанием (Self-powered functions) могут потреблять от шины не более одной единицы, даже если их собственное питание пропадает. Остальную мощность, необходимую для работы, они должны брать от других источников.

Способ питания устройства (и хаба) и максимальный ток, потребляемый от шины (с точностью до 2 мА), описываются в дескрипторе конфигурации устройства. У хаба с собственным питанием возможна ситуация, когда это питание в процессе работы теряется. В этом случае хаб должен отключиться от шины и автоматически повторно подключиться, но уже сообщая в своем дескрипторе о питании от шины. При этом временно отсоединяются и все находящиеся за ним устройства, после чего они конфигурируются уже исходя из бюджета новых условий питания.

Питание на порты хабов подается с защитой от перегрузок, из расчета 5 А на порт (это не отменяет нормы потребления). Срабатывание токовой защиты может индицироваться, например, гудком динамика системной платы ПК. Управление подачей питания у хаба может быть как общим (на все порты сразу), так и селективным — эти возможности описаны в дескрипторе нулевой конечной точки хаба.

При питании от шины до устройств доходит напряжение меньшее, чем дает хаб, из-за сопротивления питающих проводов и контактов разъемов. На каждом кабеле (между вилками A и B) в каждой из линий GND и Vbus может падать напряжение до 0,125 В. Худший случай по питанию — когда между источником питания (хабом с собственным питанием) и устройством находится один хаб с питанием от шины, вносящий свое падение напряжения (до 350 мВ). Мощный порт хаба должен под нагрузкой выдавать напряжение в диапазоне 4,75–5,25 В, маломощный — 4,4–5,25 В. Устройство, питающееся от шины, должно быть способно сообщать конфигурационную информацию при напряжении питания на вилке «A» своего кабеля от 4,4 В; маломощное устройство при таких условиях должно и нормально работать. Для нормальной работы мощного устройства требуется как минимум 4,75 В на его вилке.



Запросы к устройствам USB (управляющие передачи)

Запросы к устройству выполняются с помощью транзакций управления, адресованных к его конечным точкам типа Control. Спецификация определяет формат пакета на стадии установки, позволяющий конструировать разнообразные запросы. Запросы могут адресоваться к устройству в целом, его интерфейсу, конкретной конечной точке и иному фрагменту устройства. Формат пакета позволяет определить наличие, направление и длину посылки на стадии данных; трактовка этих данных зависит от запроса. Набор запросов включает:

  • стандартные запросы для всех устройств. Список запросов и форматы данных определены спецификацией USB;
  • запросы для класса. Список запросов и форматы данных определены стандартом для данного класса устройств;
  • специфичные запросы, определенные разработчиком конкретного устройства.

Все устройства USB имеют основной канал управления через точку EP0, к которой выполняются основные стандартизованные запросы. В устройствах могут быть и другие точки с типом Control, для них будут свои специфические запросы, но формат стадии установки у них должен быть таким же, как и для EP0, чтобы продолжение управляющей транзакции определялось из него тем же стандартным способом. Однако дополнительные точки типа Control в устройствах встречаются не часто, что объясняется сложностью их реализации. В большинстве случаев вполне можно обходиться управлением через EP0, используя «фирменные» запросы (Ven-dor request).

Устройство должно отвергать запрос, если он не поддерживается или имеет неправильные параметры. Время исполнения запроса (от подачи команды до подтверждения или отвержения) спецификацией ограничивается: общее ограничение — до 5 секунд, но запрос установки адреса должен исполняться не дольше 50 мс (иначе процесс нумерации устройств был бы слишком затяжным).

На стадии установки (Setup Stage) в 8-байтном поле данных устройству передается собственно запрос (см. таблицу), в котором указывается и направление, в котором будет передача на стадии передачи данных. Запрос идентифицируется обязательными полями bmRequestType и bRequest; содержимое полей wValue, wIndex и wLength используется не во всех запросах, неиспользуемые поля должны быть нулевыми. Стадия данных (Data Stage) используется не во всех запросах (когда ее нет, wLength = 0). На стадии состояния (Status Stage) устройство подтверждает успешное выполнение запроса (пакетом ACK) или отвергает его (пакетом STALL). До тех пор пока устройство не завершило отработку запроса (или не отвергло его), оно отвечает пакетами NAK. Получение пакета STALL от управляющей конечной точки является нормальным ответом, не требующим разблокирования данной точки.

 

Таблица. Информация, передаваемая на стадии установки

Смещение Поле Длина Содержание
0 bmRequestType 1 Характеристики запроса:
D7: направление передачи данных: 0 = от хоста
к устройству, 1 = от устройства к хосту;
D6...5: Тип 0 = стандартный, 1 = для класса,
2 = специфичный, 3 = зарезервирован
D4...0: Получатель: 0 = Устройство, 1 = Интерфейс,
2 = Точка, 3 = Другой, 4...31 = зарезервировано
1 bRequest 1 Запрос
2 wValue 2 Параметр запроса
4 wIndex 2 Индекс или смещение (использование определяется запросом)
6 wLength 2 Число байт, передаваемых в фазе данных

 



Порты

Со стороны восходящего порта хаб выглядит как и любое устройство USB. Этот порт всегда включен и разрешен, для хабов USB 1.x он всегда полноскоростной, для USB 2.0 восходящий порт всегда высокоскоростной, хотя может работать и в полноскоростном режиме.

Нисходящие порты хаба имеют комплект приемопередатчиков, изображенный в левой части того же рисунка. Хост управляет нисходящими портами и определяет их состояние, посылая запросы к контроллеру хаба. Каждый из этих портов может определить, подключено ли к нему устройство и на какой скорости оно работает. Порт может быть селективно разрешен (enabled) или запрещен (disabled) по команде от хоста; запрещение может быть и аппаратным. Аппаратно порт запрещается по событию подключения-отключения, а также по ошибке, обнаруженной хабом. Хаб игнорирует сигналы от запрещенных портов и не транслирует на них трафик. На порт может быть подана команда сброса, инициирующая соответствующую сигнализацию и уточнение типа устройства (проверяется признак HS-устройства). Также селективно любой порт может быть приостановлен (suspended), после чего для него может быть подана команда возобновления (resume) с соответствующей сигнализацией. В плане подачи питания порт может быть запитан (powered) или нет. Управление подачей питания может быть как селективным, так и общим для всех портов. Порт может оказаться не запитанным по причине срабатывания токовой защиты, причем защита тоже может быть как селективной, так и общей. В последнем случае порт может оказаться не запитанным и из-за перегрузки другого нисходящего порта. Для HS-порта возможна еще и подача команды тестирования.

Каждый нисходящий порт может находиться в одном из нижеперечисленных состояний, наблюдаемых и управляемых хостом с помощью запросов к хабу:

  • не запитан (Not powered) — на порт не подается питание по запросу Clear_Port_Power от хоста или из-за аварии питания (срабатывание токовой защиты или потеря внешнего питания). Не запитанный порт не пригоден ни к каким интерфейсным взаимодействиям. Только после подачи питания он может распознать подключение устройства и с ним взаимодействовать. Питание включается запросом Set_Port_Power;
  • не подключен (Disconnected) — порт способен только к обнаружению подключения устройства. В это состояние порт переходит из любого последующего по обнаружению отключения устройства;
  • запрещен (Disabled) — устройство подключено, но трафик и сигналы возобновления не транслируются. В это состояние порт переходит из любого последующего по запросу Port_Disable, по сигналу сброса на восходящем порте, а также при обнаружении хабом серьезной ошибки, требующей изоляции данного порта;
  • разрешен (Enabled) — устройство подключено и с ним возможен полноценный обмен данными и сигналами. В это состояние из любого другого (запитанного) порт переводится сбросом (запросом Port_Reset); кроме того, из состояния запрещен — запросом Set_Port_Enable, из состояния приостановлен — запросом Clear_Port_Suspend;
  • приостановлен (Suspended) — порт подает сигнал приостановки, трафик не транслируется, от порта воспринимается только сигнал возобновления и отключения устройства. В это состояние порт переходит по запросу Set_Port_Suspend; вернуться в состояние разрешен можно по сигналу удаленного пробуждения, запросу Clear_Port_Suspend или запросу Port_Reset.

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

Хабы могут иметь световые индикаторы состояния нисходящих портов (пару светодиодов или один двухцветный), управляемые аппаратно (логикой хаба) или программно (хост-контроллером):

  • не светится — порт не используется;
  • зеленый — нормальная работа;
  • желтый — ошибка подключенного устройства или перегрузка порта (порт автоматически отключен);
  • зеленый мигающий — программа требует внимания пользователя (Software attention);
  • желтый мигающий — аппаратура требует внимания пользователя (Hardware attention), например, мощное устройство подключено к маломощному порту.


Структуры данных и регистры контроллера OHC

Все структуры данных OHC, расположенные в системной памяти, выровнены по границе параграфа (четыре младших бита адреса — нулевые). Для работы с OHC в памяти размещают дескрипторы конечных точек (ED) выбранных интерфейсов сконфигурированных устройств, дескрипторы передач (TD) для них и коммуникационную область HCCA. Дескрипторы передач подключаются драйвером к очередям требуемых конечных точек. Дескрипторы исполненных передач (завершенных нормально или снятых аварийно) контроллером подключаются к очереди Done Queue. Буфер данных для каждого дескриптора передачи может размещаться в одной или двух физических страницах, физические адреса этих страниц определяются по физическому адресу начала (начальное значение CBP) и физическому адресу конца буфера. Дескрипторы передач делятся на два типа: общий (для передач Bulk, Control, Interrupt) и изохронный.

Дескриптор конечной точки (ED) имеет размер 4 двойных слова (16 байт), его формат приведен на рисунке ниже, назначение полей приведено ниже:

  • FA (FunctionAddress) — адрес устройства;
  • EN (EndpointNumber) — номер точки;
  • D (Direction) — направление передачи: 01 — OUT; 10 — IN; 00, 11 — брать из поля PID дескриптора передачи TD;
  • S (Speed) — скорость: 0 — FS, 1 — LS;
  • K (sKip) — пропустить (не начинать транзакций с данной точкой);
  • F (Format) — признак формата TD, связанного с данной точкой: 0 — общий (Bulk, Control, Interrupt), 1 — дескриптор изохронной передачи;
  • MPS (MaximumPacketSize) — максимальный размер пакета;
  • TailP (TD Queue Tail Pointer) — указатель на конец очереди TD, если совпадает с HeadP — очередь пуста;
  • HeadP (TD Queue Head Pointer) — указатель на очередной TD, который должен быть исполнен для данной точки;
  • H (Halted) — признак останова точки;
  • C (toggleCarry) — текущее значение переключателя Toggle Bit;
  • NextED (Next Endpoint Descriptor) — указатель на дескриптор следующей конечной точки (если ноль, то эта точка — последняя в списке).

 

Формат общего дескриптора передач приведен на рисунке 2 (см. выше). Дескриптор позволяет описывать передачу данных указанной длины в пределах 8 кбайт. Количество транзакций для передачи контроллер определяет сам из поля длины пакета в дескрипторе точки (ED) и длины буфера; количество транзакций при приеме определяется длиной пакетов, переданных устройством. Назначение полей общего дескриптора передач приведено ниже:

  • R (bufferRounding) — требование совпадения длины последнего принимаемого пакета с объявленной длиной буфера (обнаружение коротких пакетов): 0 — сообщать об ошибке, если длина последнего пакета меньше длины буфера, 1 — не реагировать на несовпадение длины;
  • DP (Direction/PID) — тип маркера (направление, должно соответствовать полю D в ED): 00 — SETUP, 01 —OUT, 10 — IN, 11 — резерв;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • T (DataToggle) — поле, используемое для генерации и сравнения переключателя типа пакетов данных. Вместе с битом C из ED обеспечивает корректное переключение при передачах данных, описанных серией TD. При постановке в очередь TD для передач типов Bulk и Interupt драйвер должен установить T = 00; для передач типа Control в фазе Setup драйвер должен установить T = 10; в фазе Status и в первой фазе данных — T = 11. Дальнейшие модификации поля выполняет контроллер;
  • EC (ErrorCount) — счетчик ошибок передачи для текущей транзакции. Если при EC = 2 происходит ошибка, ее код помещается в CC и вся передача аварийно завершается. При успешном завершении транзакции счетчик обнуляется;
  • CC (ConditionCode) — состояние последней попытки транзакции
  • CBP (Current Buffer Pointer) — текущий физический адрес в буфере, по которому будет записан или прочитан очередной передаваемый пакет. После успешного завершения передачи поле обнуляется, при нештатном завершении — указывает на текущее положение;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD.

Формат дескриптора изохронной передачи приведен на рисунке ниже. Дескриптор позволяет описывать передачу данных длиной до 8 кбайт, состоящую из 1–8 транзакций (их количество задано в дескрипторе). Транзакции исполняются в последовательных кадрах, начиная с кадра с указанным номером. Длина пакета в каждой из этих транзакций вычисляется из значений полей OffsetN смежных транзакций (возможны и транзакции с нулевой длиной поля данных). Физический адрес буфера для каждой из этих транзакций определяется следующим образом: младшие 12 бит берутся из младших 12 бит соответствующего поля Offset, старшие биты (номер физической страницы) берутся либо из поля BPO (если в поле Offset бит 12 = 0), или из BE (если в поле Offset бит 12 = 1). Контроллер нормально отрабатывает переход буфера с одной страницы на другую даже в середине пакета. Назначение полей дескриптора изохронной передачи приведено ниже:

  • SF (StartingFrame) — младшие 16 бит номера кадра, в котором должен быть передан первый пакет;
  • DI (DelayInterrupt) — задержка прерывания по отработке передачи: 000–110 — задержка (число пропущенных кадров), 111 — не вызывать прерывание;
  • FC (FrameCount) — число пакетов данных, описанных в данном TD (0 — 1 пакет, 7 — 8 пакетов);
  • CC (ConditionCode) — код завершения на момент отправки TD в очередь выполненных заданий;
  • BP0 (BufferPage0) — физический номер страницы с первым байтом буфера данных;
  • NextTD — указатель на следующий дескриптор передачи для данной точки;
  • BE (Buffer End) — физический адрес последнего байта в буфере для данного TD;
  • Offset0… Offset7 — смещение, используемое для определения размера и стартового адреса данных каждого пакета;
  • PSW0…PSW7 — слово состояния каждого пакета: биты [15:12] — код завершения, биты [10:0] — длина принятого пакета данных (в транзакциях OUT — 0), бит 11=0.

Коды завершения для всех типов передач приведены в таблице ниже.

Код CC Условие
0000 NoError — нормальное завершение без ошибок
0001 CRC — последний принятый пакет содержит ошибку CRC
0010 BitStuffing — последний принятый пакет содержит ошибку вставки бит
0011 DataToggleMismatch — последний принятый пакет данных имеет PID, не отвечающий ожидаемому значению переключателя
0100 Stall — конечная точка остановлена (получен одноименный пакет подтверждения)
0101 DeviceNotResponding — устройство не отвечает
0110 PIDCheckFailure — ошибка контроля достоверности поля PID
0111 UnexpectedPID — прием неожиданного или недопустимого PID
1000 DataOverrun — пакет данных от устройства длиннее разрешенного в поле MPS дескриптора точки
1001 DataUnderrun — точка вернула пакет, меньший чем MPS, и недостаточный для заполнения указанного буфера
1010, 1011 Резерв
1100 BufferOverrun — во время приема данных контроллер не успел записать данные в системную память
1101 BufferUnderrun — во время вывода данных контроллер не успел считать данные из системной памяти
111x NotAccessed — не было обработки (драйвер записывает этот код в TD перед помещением его в очередь)

 

Таблица. Формат коммуникационной области HCCA контроллера OHC

Смещение Длина Назначение
0 128 HccaInterrruptTable — таблица дескрипторов точек прерываний, 32 двойных слова, указывающих на дескрипторы EP
80 2 HccaFrameNumber — текущий номер кадра, модифицируется контроллером перед обходом списка периодических передач
82h 2 HccaPad1 — это слово контроллер обнуляет, когда модифицирует значение номера кадра
84h 4 HccaDoneHead — указатель на очередь исполненных передач. Контроллер модифицирует указатель по мере исполнения передач и сигнализирует об этом установкой бита WDH в регистре HcInterruptStatus. Указатель не будет повторно модифицироваться, пока программа не сбросит бит WDH. Бит 0 указателя используется для сигнализации о наличии иных незамаскированных условий прерываний (если обработчик прерывания, считывая указатель, получает нулевое значение бита, он может не анализировать регистр HcInterruptStatus)
88h 116 Резерв для контроллера

Кроме дескрипторов драйвер OHCI взаимодействует с контроллером через коммуникационную область в системной памяти — HCCA. На начало этой области указывает регистр HCCA.

Для оперативного взаимодействия драйвера и хост-контроллера в OHC имеется блок операционных регистров, приписанный к пространству памяти (его положение определяется регистрами BAR в конфигурационном пространстве устройства PCI, каковым и является OHC). К этому блоку система должна обеспечивать доступ и в режиме SMM. Размер блока регистров определяется числом нисходящих портов (NDP) корневого хаба, входящего в OHC; при наличии регистров поддержки эмуляции традиционного контроллера клавиатуры и мыши размер достигает 272 байт. Все регистры, кроме специальных регистров эмуляции, требуют 32-разрядных обращений. Операционные регистры обеспечивают управление хост-контроллером в целом, планирование загрузки кадров, связь контроллера с памятью и управление корневым хабом.

Таблица. Операционные регистры OHC

Смещение Назначение
Регистры общего управления и состояния OHC
00h HcRevision — ревизия контроллера: биты [7:0] — номер версии в BCD-формате, бит 8 — признак поддержки эмуляции контроллера клавиатуры и мыши, остальные биты не используются
04h HcControl — управление операционными режимами контроллера. Назначение полей:
CBSR (ControlBulkServiceRatio) — соотношение числа обслуживаемых непустых ED для точек типов Control и Bulk: 0 — 1:1, 1 — 2:1, 2 — 3:1, 3 — 4:1, Определяет приоритет управляющих передач относительно передач массивов
PLE (PeriodicListEnable) — разрешение обслуживания списка периодических транзакций (в следующем кадре)
IE (IsochronousEnable) — разрешение обслуживания изохронных передач (в следующем кадре)
CLE (ControlListEnable) — разрешение обслуживания управляющих передач (в следующем кадре)
BLE (BulkListEnable) — разрешение обслуживания передач массивов (в следующем кадре)
HCFS (HostControllerFunctionalState) — состояние хост-контроллера в плане USB: 00 — Reset, 01 — Resume, 10 — нормальный режим, 11 — Suspend
IR (InterruptRouting) — маршрутизация прерываний (сигнализация событий, указанных в регистре HcInterruptStatus: 0 — нормальные прерывания, 1 — SMI
RWC (RemoteWakeupConnected) — признак подключенности контроллера к системе «пробуждения» хоста
RWE (RemoteWakeupEnable) — разрешение сигнализации «пробуждения» хоста по установке бита ResumeDetected в регистре HcInterruptStatus
08h HcCommandStatus — управление и состояние контроллера.Назначение полей:
HCR (HostControllerReset) — сброс контроллера (обнуляется контроллером по завершении сброса)
CLF (ControlListFilled) — признак наличия дескрипторов в очереди управляющих передач (если бит обнулен, контроллер и не начнет обход списка ED точек управления). Устанавливается драйвером по помещении дескриптора в очередь, дальше отслеживается и модифицируется контроллером.
BLF (BulkListFilled) — признак наличия дескрипторов в очереди передач массивов (аналогично CLF)
OCR (OwnershipChangeRequest) — запрос передачи права управления контроллером
SOC (SchedulingOverrunCount) — счетчик ошибок планирования (переполнений)
0Ch HcInterruptStatus — идентификация событий, вызывающих прерывание. Назначение полей:
SO (SchedulingOverrun) — признак переполнения при планирования кадра (транзакция не умещается до конца кадра)
WDH (WritebackDoneHead) — признак помещения дескриптора в очередь выполненных заданий
SF (StartofFrame) — признак начала кадра
RD (ResumeDetected) — признак получения сигнала Resume
UE (UnrecoverableError) — признак неисправимой ошибки, не связанной с USB (требуется сброс контроллера)
FNO (FrameNumberOverflow) — переполнение счетчика кадров (перенос из 15-го разряда)
RHSC (RootHubStatusChange) — признак смены состояния корневого хаба
OC (OwnershipChange) — признак передачи права управления контроллером (вызывает SMI)
10h HcInterruptEnable — разрешение прерываний по событиям. Назначение полей аналогично предыдущему, дополнительно имеется бит MIE (MasterInterruptEnable) — общее разрешение прерываний. При записи единичное значение каждого бита разрешает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
14h HcInterruptDisable — запрет прерываний по событиям. Назначение полей аналогично предыдущему. При записи единичное значение каждого бита запрещает соответствующее условие, нулевое — игнорируется. Чтение возвращает текущее состояние (разрешенные условия)
Указатели областей памяти
18h HcHCCA — физический адрес HCCA (биты [7:0]=0)
1Ch HcPeriodCurrentED — текущий физический адрес дескриптора ED точки периодических передач (биты [3:0]=0), устанавливается контроллером, драйвер может только читать
20h HcControlHeadED — физический адрес первого дескриптора точки управления (биты [3:0]=0), устанавливается драйвером
24h HcControlCurrentED — физический адрес текущего дескриптора точки управления (биты [3:0]=0), устанавливается контроллером
28h HcBulkHeadED — физический адрес первого дескриптора точки передач массивов (биты [3:0]=0), устанавливается драйвером
2Ch HcBulkCurrentED — физический адрес текущего дескриптора точки передач массивов (биты [3:0]=0), устанавливается контроллером
30h HcDoneHead — физический адрес начала очереди завершенных передач (биты [3:0]=0), устанавливается контроллером
Регистры управления кадром
34h HcFmInterval — параметры кадра:
Биты [13:0] — FI (FrameInterval), длительность кадра (в bt), по умолчанию 2EDFh (11999)
Биты [30:16] — FSMPS (FSLargestDataPacket), значение максимального размера пакета данных, загружаемое в счетчик Data Packet Counter в начале каждого кадра (счетчик отражает длину пакета данных, допустимую в текущий момент времени без переполнения планирования)
Бит 31 — FIT (FrameIntervalToggle), переключением этого бита драйвер сигнализирует о смене длительности кадр
38h HcFmRemaining, остаток кадра:
Биты [13:0] — FR (FrameRemaining), текущее количество битовых интервалов до конца кадра. Автоматически декрементируется; по обнулению загружается значением из FI и генерируется SOF;
Бит 31 — FRT (FrameRemainingToggle), принимает значение FIT по обнулению FI
3Ch HcFmNumber — номер кадра FN (биты [15:0]), автоматически меняется на границе кадра
40h HcPeriodicStart — момент начала обхода списка периодических транзакций PS (биты [13:0]), обычно устанавливается на 10% меньше FI. Контроллер приступает к периодическим транзакциям, когда FR достигает значения PS
44h HcLSThreshold — порог LST (биты [11:0]), до которого контроллер может выполнять LS-транзакции с максимальным (8 байт) размером пакета. Эти транзакции могут начинаться только при FR≥LST, по умолчанию LST=628h (1576)
Регистры управления и состояния корневого хаба
48h HcRhDescriptorA — дескриптор-A корневого хаба. Назначение полей:
NDP (NumberDownstreamPorts) — число нисходящих портов (1–15)
PSM (PowerSwitchingMode) — режим управления питанием портов: 1 — селективное управление, 0 — общее
NPS (NoPowerSwitching) — признак отсутствия ключа подачи питания (1 — порты запитаны постоянно)
DT (DeviceType) — тип устройства: всегда 0, поскольку корневой хаб не может быть компаундным устройством
OCPM (OverCurrentProtectionMode) — режим сообщения о срабатывании токовой защиты питания портов: 0 — коллективное, 1 — индивидуальное. Действительно только при NOCP=0
NOCP (NoOverCurrentProtection) — признак невозможности сообщения о перегрузке
POTPGT (PowerOnToPowerGoodTime) — время ожидания перед обращением драйвера к контроллеру после подачи питания на порт (в 2-мс интервалах)
4Ch HcRhDescriptorB — дескриптор-B корневого хаба:
Биты [15:0] — DR (DeviceRemovable), признаки отсоединяемости устройств от портов (бит 1 — порт 1,…бит 15 — порт 15)
Биты [31:16] — PPCM (PortPowerControlMask), маски управления питанием портов: 0 — глобальное, 1 — селективное
50h HcRhStatus — регистр состояния корневого хаба. Назначение полей:
LPS (LocalPowerStatus) — чтение всегда дает 0, запись «1» выключает питание портов с глобальным управлением, запись «0» не имеет значения
OCI (OverCurrentIndicator) — индикатор перегрузки для глобальной защиты по току
DRWE (DeviceRemoteWakeupEnable) — запись «1» разрешает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
LPSC (LocalPowerStatusChange) — чтение всегда дает 0, запись «1» включает питание портов с глобальным управлением, запись «0» не имеет значения
OCIC (OverCurrentIndicatorChange) — запись «1» сбрасывает индикатор перегрузки для глобальной защиты, запись «0» не имеет значения
CRWE (ClearRemoteWakeupEnable) — запись «1» запрещает выход из состояния Suspend по смене состояния подключения портов, запись «0» не имеет значения
54h HcRhPortStatus[1], состояние первого порта корневого хаба.Назначение полей:
CCS: чтение (CurrentConnectStatus) — текущее состояние подключения к порту:
1 — подключено устройство, 0 — нет; запись «1» запрещает порт, запись «0» не имеет эффекта
PES (PortEnableStatus) — состояние разрешения порта: 0 — Disabled, 1 — Enabled; запись «1» разрешает порт, запись «0» не имеет эффекта
PSS (PortSuspendStatus) — состояние приостановки порта: 0 — не приостановлен, 1 — приостановлен или находится в процессе возобновления; запись «1» приостанавливает порт, запись «0» не имеет эффекта
POCI: чтение (PortOverCurrentIndicator) — перегрузка порта по питанию (только при селективной защите портов): 1 — защита сработала, 0 — нет; запись «1» инициирует возобновление порта (resume), запись «0» не имеет эффекта
PRS (PortResetStatus) — чтение состояния сброса порта: 1 — подается сигнал Reset, 0 — нет; запись «1» инициирует подачу сигнала Reset, запись «0» не имеет эффекта.
PPS (PortPowerStatus) — состояние питания порта: 0 — порт не запитан, 1 — порт запитан; запись «1» включает питание порта при селективном управлении, запись «0» не имеет эффекта
LSDA (LowSpeedDeviceAttached) — признак низкой скорости: 1 — обнаружено подключение LS-устройства, 0 — нет
CSC (ConnectStatusChange) — признак смены состояния подключения порта, сбрасывается записью «1»
PESC (PortEnableStatusChange) — признак смены состояния разрешения порта, сбрасывается записью «1»
PSSC (PortSuspendStatusChange) — признак завершения последовательности возобновления для порта, сбрасывается записью «1»
OCIC (PortOverCurrentIndicatorChange) — признак смены состояния индикатора селективной защиты порта, сбрасывается записью «1»
PRSC (PortResetStatusChange) — признак завершения формирования сигнала Reset, сбрасывается записью «1»
Состояние портов корневого хаба (аналогично предыдущему)
54h+4×NDP HcRhPortStatus[NDP], состояние последнего порта корневого хаба (аналогично предыдущему)
Регистры поддержки эмуляции контроллера клавиатуры и мыши (KBC)
100h HceControl — управление эмуляцией
104h HceInput — эмуляция входных буферов KBC: программный вывод байта по адресу порта 60h или 64h вызывает запись данных в биты [7:0] этого регистра, биты [31:8] — резерв
108h HceOutput — эмуляция выходного буфера KBC: программный ввод байта из порта 60h вернет данные из бит [7:0] этого регистра (и сбросит флаг BufferFull в HceStatus), биты [31:8] — резерв
10Ch HceStatus — эмуляция регистра состояния KBC

 

При разрешенной эмуляции контроллера клавиатуры и мыши контроллер OHC перехватывает (декодирует) обращения по адресам ввода/вывода 60h и 64h:

  • инструкция IN, обращенная к порту 60h, вернет байт из регистра HceOutput, а также установит в регистре HceStatus флаг OutputFull = 0;
  • инструкция OUT, обращенная к порту 60h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 1 и CmdData = 0;
  • инструкция IN, обращенная к порту 64h, вернет байт текущего состояния из регистра HceStatus;
  • инструкция OUT, обращенная к порту 64h, запишет байт в регистр HceInput, а также установит в регистре HceStatus флаги InputFull = 0 и CmdData = 1.

ПО эмуляции отрабатывает эти обращения, пользуясь клавиатурой и мышью, подключенными к USB. Ряд обращений требует действий, которые эмулятор должен выполнить невидимо для ПО. Эти действия вызывают условие прерывания для эмулятора, которое может выполняться как системное прерывание SMI. При этом оказывается, что с хост-контроллером должны взаимодействовать как нормальный драйвер ОС, так и драйвер эмулятора, работающий в режиме системного управления (SMM). Чтобы корректно передавать право на управление контроллером между этими драйверами, в регистрах HcCommandStatus и HcInterruptStatus предусмотрены соответствующие биты.

 

Таблица. Назначение бит регистров управления и состояния эмуляции

Бит Назначение
Регистр HceControl
0 EmulationEnable, разрешение эмуляции
1 EmulationInterrupt, признак условия прерывания для эмуляции
2 CharacterPending, разрешение прерывания эмуляции по обнулению бита OutputFull в регистре HceStatus (требуется следующий байт от клавиатуры или мыши)
3 IRQEn, разрешение генерации IRQ1 или IRQ12 по установке бита OutputFull в регистре HceStatus
4 ExternalIRQEn, разрешение формирования сигнала прерывания эмуляции по сигналу IRQ1 и IRQ12 от KBC (независимо от состояния EmulationEnable)
5 GateA20Sequence, признак команды управления вентилем GateA20, устанавливается по записи байта D1h в порт 64h, сбрасывается по записи любого другого значения в этот порт
6 IRQ1Active, признак сигнала IRQ1 от KBC (сбрасывается записью «1»)
7 IRQ12Active, признак сигнала IRQ12 от KBC (сбрасывается записью «1»)
8 A20State, индикатор состояния сигнала GateA20 от KBC
9-31 Резерв (0)
Регистр HceStatus
0 OutputFull, выходной буфер контроллера полон. Сбрасывается при чтении порта 60h. При установке этого бита и при IRQEn = 1 вырабатывается IRQ1 (при AuxOutputFull = 0) или IRQ12 (при AuxOutputFull = 1)
1 InputFull, входной буфер полон. Устанавливается при записи в порт 60h или 64h (кроме команд управления вентилем GateA20)
2 Flag, системный флаг для определения «холодной» или «теплой» загрузки
3 CmdData, признак команды или данных для контроллера: запись в порт 60h сбрасывает бит, запись в порт 64h — устанавливает
4 Inhibit Switch, состояние ключа запрета клавиатуры (1 — клавиатура не запрещена)
5 AuxOutputFull, признак прихода данных от мыши
6 Time-out, признак тайм-аута при обмене с клавиатурой
7 Parity, признак ошибки четности при обмене с клавиатурой


Разрешение проблем при подключении устройств

Все спецификации USB разрабатывались (и разрабатываются) в расчете на полную поддержку Plug and Play и «горячего» подключения-отключения устройств. При этом в идеальном варианте с пользователя снимаются все заботы по конфигурированию подключаемых устройств и установке его программного обеспечения. Однако на практике процесс подключения нового устройства происходит не всегда в таком «безоблачном» варианте. Проблемы, с которыми сталкиваются пользователи готовых устройств, как правило, сводятся к поиску подходящих драйверов и прикладного ПО. Конечно же, не надо забывать и о таких простых неполадках, как случайное отключение (опциями CMOS Setup) контроллера USB, находящегося на системной плате, а также ошибок подключения дополнительных разъемов USB.

В ОС Windows каждое подключенное устройство USB отображается в Диспетчере устройств (Device Manager). Для наглядности удобно в меню Вид выбрать опцию Устройства по подключению, тогда устройства будут отображаться в виде деревьев, «растущих» из шины PCI. Каждое дерево начинается со своего хост-контроллера, к которому подключен корневой концентратор (Root Hub). Заметим, что для каждого дерева (то есть для каждого хост-контроллера) адреса устройств USB назначаются независимо. К сожалению (но для удобства пользователя), диспетчер устройств Windows отображает только подключенные устройства и не отображает свободных портов хабов. Это усложняет понимание организации портов и контроллеров. Более информативна утилита USB View (от Microsoft), которая подробнее отображает дерево устройств (хост-контроллеры, корневые хабы, промежуточные хабы и конечные устройства). Для каждого элемента отображаются дескрипторы устройств, их конечных точек, а также состояние подключения:

  • номер выбранной конфигурации (Current Config Value);
  • скорость работы (Device Bus Speed);
  • адрес устройства (Device Address);
  • число открытых каналов (Open Pipes, не считая основного канала сообщений);
  • cостояние подключения (ConnectionStatus).

Для хабов в дереве отображаются ветки, соответствующие всем имеющимся его портам. Это позволяет определить внутреннюю структуру хост-части системы. Так, например, можно увидеть в компьютере с шестью портами USB и провозглашенной поддержкой USB 2.0 «Расширенный хост-контроллер USB 2.0» (EHC) c шестипортовым корневым хабом и три «Универсальных хост-контроллера USB», у каждого из которых имеется по двухпортовому корневому хабу. В этом случае HSустройство можно подключать к любому порту и оно маршрутизирующей логикой будет связано с контроллером EHC. Для устройств FS и LS каждая пара портов подключается к своему контроллеру-компаньону (UHC). В такой системе можно говорить о суммарной пропускной способности шины USB, равной 480 + 3×12 = 516 Мбит/с. Правда, из этого следует вычесть накладные расходы и не забывать о возможных ограничениях со стороны шины PCI, к которой подключены хост-контроллеры, и со стороны контроллера системной памяти, которой контроллеры пользуются очень активно. Если бы мы в шестипортовой системе увидели расширенный контроллер с четырехпортовым корневым хабом, это означало бы, что поддержка USB 2.0 имеется только на четырех портах из шести.

Еще более развернутую информацию об устройствах USB дают утилиты, поставляемые для разработчиков производителями микросхем USB. Примером может быть утилита USB Monitor от Cypress Semiconductors, позволяющая прочитать все дескрипторы, имеющиеся у устройства USB.

Для облегчения отладки собственных устройств полезно как-нибудь отображать информацию о текущем состоянии его интерфейсной части (блока SIE,). Это отображение должно быть автономным (индикация на самом устройстве, а не средствами хост-компьютера). На начальном этапе отладки достаточно индицировать четыре состояния:

  • «Запитано» (Powered State);
  • «Дежурное» состояние (Default State);
  • «Адресовано» (Addressed State);
  • «Сконфигурировано» (Configured State).

Устройство, подключаемое к шине USB, должно последовательно пройти от состояния «запитано» до «сконфигурировано». По тому, в каком состоянии «застревает» подключаемое устройство, можно судить о событиях, происшедших в системе, и найти неполадки.

Если устройство при подключении «зависает» в состоянии «запитано», это может быть вызвано рядом причин:

  • хост не получает сигнала о подключении устройства. Следует проверить наличие высокого логического уровня на линии D+ (для FS/HS-устройства) или D(для LS-устройства), который должно обеспечить устройство. Этот сигнал может не дойти до хоста при неплотном соединении разъема USB (в нем сигнальные цепи замыкаются позже питающих);
  • хост не реагирует на сигнал подключения. Нормально хост реагирует посылкой сигнала шинного сброса — занулением линии D+ или D- на 10–20 мс, этот импульс легко можно увидеть с помощью осциллографа. «Заснувший» хост может и не реагировать на подключение (не посылать сигнал сброса). Доводилось наблюдать, как хост с ОС UNIX перестает реагировать на подключение LS-устройства (даже стандартной мыши) после многократных (с интервалом в несколько секунд) подключений/отключений его к одному и тому же порту корневого хаба. После этого подключение того же устройства к другому порту воспринимается нормально. Более того, последующее подключение этого устройства к порту, на котором реакция на подключение прекращалась, снова воспринимается нормально;
  • устройство не реагирует на сигнал шинного сброса. Нормально устройство должно по сигналу шинного сброса перейти в «дежурное» состояние. Если устройство «зависает» в «дежурном» состоянии, это означает его неспособность сообщить дескрипторы и исполнить запрос назначения уникального адреса. Здесь определить неисправность несколько сложнее, поскольку требуется просмотреть пакеты запросов, принимаемые и передаваемые устройством. Причины некорректного обмена пакетами могут быть как в электронике, так и в микропрограммном обеспечении (firmware). В электронной части, например, может быть неправильная частота генератора, синхронизирующего SIE контроллера устройства USB, или неисправности в сигнальных цепях. В микропрограммном обеспечении следует проверить дескрипторы, сообщаемые устройством.
    Зависание в состоянии «адресовано» может означать, что подключенным устройством никто в системе не заинтересовался и не пытается сконфигурировать. Это происходит, например, когда ОС не может связать с обнаруженным устройством подходящий драйвер. Обнаруженное устройство идентифицируется кодами VID (код производителя) и PID (код продукта) в своих дескрипторах. Также это может происходить в случае подключения HS-устройства, критичного к скорости передачи, к FS-порту.
    В поддержке устройств USB, по крайней мере в ОС Windows, наблюдается странность (с точки зрения автора) в учете устройств. Каждое вновь подключенное устройство после установки его ПО поддержки оставляет в реестре Windows запись, в которой некоторый идентификатор устройства связывается с именами модулей ПО, его поддерживающих. Странность заключается в том, что вместе с такими бесспорными идентификаторами устройства, как VID и PID, в реестре фиксируется и номер порта. Если то же устройство переключить в другой порт, то ОС это воспримет как подключение нового(!) устройства и снова начнет установку ПО поддержки, создавая и новую запись в реестре. Отключение устройства не вызывает удаления записи из реестра, так что реестр будет «обрастать» лишними записями. Само по себе это не так уж важно (вопрос о компактности записей, похоже, давно уже решен в пользу лени), но ПО некоторых устройств отказывается загружаться (или работать), когда в реестре прописан его двойник с другим адресом. В этой ситуации приходится либо возвращать устройство в порт первоначального подключения (что не всегда удобно), либо вручную чистить реестр (что не к лицу рядовому пользователю). Вероятная причина этой странности — упрощение идентификации нескольких однотипных устройств, одновременно подключенных к компьютеру. Использование номера порта, который является сравнительно случайным (пользователь подключает устройство в первый попавшийся разъем), для идентификации устройства следовало бы заменить на уникальный идентификатор конкретного экземпляра устройства. Для этого спецификацией USB в дескрипторах устройства определены все необходимые элементы, включая строковый дескриптор с серийным номером. «Глубина залегания» этой странности — типовые драйверы устройств (подвластные их разработчикам) или системный драйвер USBD (за него отвечает разработчик ОС), на момент написания книги автором не выяснена.


Подкатегории