GPIO-Based аппаратные ресурсы

Начиная с Windows 8, пин-коды общего назначения (GPIO), управляемые драйвером контроллера GPIO, доступны для других драйверов в качестве аппаратных ресурсов, управляемых системой. Пин-коды ввода-вывода GPIO, которые настраиваются как входные данные или выходные данные, доступны в качестве нового типа ресурсов Windows, ресурсов ввода-вывода GPIO. Кроме того, пин-коды прерываний GPIO, которые настраиваются как входные данные запроса прерывания, доступны как обычные ресурсы прерывания Windows.

Ресурс ввода-вывода GPIO представляет собой набор одного или нескольких контактов GPIO, с которых драйвер периферийного устройства может считывать данные или на которые записывать данные. Windows скрывает сведения о базовой реализации контактов ввода-вывода GPIO, чтобы драйверы периферийных устройств могли быть разработаны для управления абстрактными ресурсами ввода-вывода GPIO. Драйверы периферийных устройств, использующие эти абстрактные ресурсы, могут работать на разных платформах независимо от оборудования контроллера GPIO, реализующего ресурсы. Ресурс ввода-вывода GPIO представлен дескриптором WDFIOTARGET, который связывает этот ресурс с конкретным драйвером контроллера GPIO, который владеет базовым контактом или контактами GPIO.

Как правило, контакт на контроллере GPIO можно настроить либо для ввода, либо для вывода в зависимости от возможностей оборудования контроллера и устройства, физически подключенного к контакту. Таким образом, драйвер может открыть логическое соединение к этому пину только для операций записи или чтения, но не для обоих операций. Однако это ограничение накладывается оборудованием, а не расширением платформы GPIO (GpioClx). Если оборудование позволяет настроить контакт ввода-вывода для выполнения операций ввода и вывода, GpioClx позволяет драйверу открыть логическое соединение с контактом для операций чтения и записи.

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

На следующей схеме показан пример назначения ресурсов на основе GPIO двум драйверам периферийных устройств:

пример назначения ресурсов на основе gpio.

На приведенной выше схеме следующие три ресурса на основе GPIO назначаются драйверу периферийных устройств A:

  • Два пин-кода ввода данных
  • Пин для вывода данных
  • Входной пин-код прерывания

Следующие два ресурса на основе GPIO назначаются драйверу периферийных устройств B:

  • Пин-код ввода данных
  • Входной пин-код прерывания

Драйверы A и B получают свои назначенные ресурсы в функциях обратного вызова EvtDevicePrepareHardware. Если драйвер получает в качестве ресурса набор одного или нескольких GPIO-пинов ввода-вывода, драйвер может установить подключение к этим пинам для доступа к ним. Драйвер получает дескриптор WDFIOTARGET для идентификации подключения и отправляет запросы ввода-вывода в этот дескриптор для чтения или записи в эти пин-коды.

Примеры кода, показывающие, как подключиться к набору контактов ввода-вывода GPIO и отправлять запросы ввода-вывода в эти пин-коды, см. в следующих разделах:

Подключение драйвера KMDF к контактам ввода-вывода GPIO

В обоих разделах функция IoRoutine в примере кода открывает GPIO-пин для чтения или записи в зависимости от значения параметра ReadOperation. Если ресурс открыт для операций чтения (DesiredAccess = GENERIC_READ), контакты в ресурсе настраиваются как входы, а запрос IOCTL_GPIO_READ_PINS отправленный ресурсу контактов, считывает входные значения на этих контактах. GpioClx не позволяет отправлять запрос IOCTL_GPIO_WRITE_PINS на набор входных контактов и завершает такой запрос со статусом ошибки STATUS_GPIO_OPERATION_DENIED. Аналогичным образом, если ресурс контактов открыт для записи (DesiredAccess = GENERIC_WRITE), контакты в ресурсе настраиваются в качестве выходов, а запрос IOCTL_GPIO_WRITE_PINS, отправляемый в ресурс контактов, задает значения в выходных защелках, которые управляют этими контактами. Как правило, отправка запроса IOCTL_GPIO_READ_PINS к набору выходных контактов просто считывает последние значения, записанные на выходные защелки.

Чтобы использовать ресурс прерывания для получения прерываний, клиентский драйвер должен подключить подпрограмму службы прерываний (ISR) к прерыванию. Как правило, драйвер делает это подключение путем вызова метода WdfInterruptCreate (или, возможно, подпрограммы IoConnectInterruptEx ). Дополнительные сведения об прерываниях KMDF см. в разделе "Создание объекта прерывания".

В отличие от устройств Plug and Play, которые могут быть динамически подключены к аппаратной платформе и отключены от нее, устройство контроллера GPIO постоянно подключено. Кроме того, предполагается, что подключения между пин-узлами GPIO и периферийным устройством являются постоянными. (Или, если периферийное устройство может быть отключено из слота, слот выделен для этого устройства.) Таким образом, доступные ресурсы GPIO исправлены и могут быть указаны в встроенном ПО платформы. Аналогичным образом предполагается, что драйверы периферийных устройств, использующие ресурсы GPIO, используют выделенные наборы ресурсов GPIO. Таким образом, требования к ресурсам для этих драйверов устройств можно указать в встроенном ПО платформы.

Если встроенное ПО платформы назначает набор контактов GPIO в качестве ресурса ввода-вывода GPIO, встроенное ПО указывает, можно ли открывать пин-коды в этом ресурсе для чтения, для операций записи или для операций чтения и записи.

Если драйвер периферийных устройств использует несколько ресурсов ввода-вывода GPIO, этот драйвер должен учитывать порядок перечисления этих ресурсов диспетчером PnP. Например, если драйвер использует два пин-кода ввода-вывода GPIO, но эти пин-коды должны быть доступны независимо и в отдельный момент времени, встроенное ПО платформы должно описать каждый пин-код как отдельный ресурс ввода-вывода GPIO. Диспетчер PnP перечисляет эти ресурсы в том порядке, в котором они описаны в встроенном ПО платформы, который должен соответствовать порядку, ожидаемому драйвером.

После того как драйвер периферийных устройств открывает подключение к ресурсу ввода-вывода GPIO, IOCTL_GPIO_READ_PINS или IOCTL_GPIO_WRITE_PINS запрос, который этот драйвер отправляет этому подключению, обращается ко всем контактам в ресурсе. Если драйвер иногда должен получить доступ только к подмножеству этих контактов, это подмножество должно быть назначено драйверу в качестве отдельного ресурса.

Дополнительные сведения о запросах IOCTL_GPIO_READ_PINS, включая сопоставление пин-кодов ввода данных с битами в выходном буфере запроса, см. в IOCTL_GPIO_READ_PINS. Дополнительные сведения о запросах IOCTL_GPIO_WRITE_PINS, включая сопоставление битов в входном буфере запроса с выводными контактами данных, см. в IOCTL_GPIO_WRITE_PINS.