Методы поддержки драйверов в DDI GpioClx
Расширение платформы GPIO (GpioClx) доступно начиная с Windows 8. Системные методы в DDI GpioClx реализованы в драйвере режима ядра GpioClx, Msgpioclx.sys. Этот драйвер экспортирует точки входа для методов поддержки драйвера GpioClx. Начиная с Windows 8 Msgpioclx.sys является стандартным компонентом операционной системы.
Во время сборки драйверы контроллера GPIO статически связываются с точками входа DDI в библиотеке заглушки GpioClx Msgpioclxstub.lib. Во время выполнения эта библиотека выполняет необходимое согласование версии драйвера и версии для динамического связывания с соответствующими точками входа в Msgpioclx.sys.
Драйвер контроллера GPIO, которому требуется определенная версия Msgpioclx.sys, может безопасно связаться с версией Msgpioclx.sys с более высоким номером версии. Однако этот драйвер не может связаться с версией Msgpioclx.sys с более низким номером версии.
Регистрация драйвера
Чтобы зарегистрироваться в качестве клиента GpioClx, драйвер контроллера GPIO вызывает метод GPIO_CLX_RegisterClient . Как правило, драйвер вызывает этот метод из своей подпрограммы DriverEntry . Во время этого вызова драйвер передает регистрационный пакет методу . Этот пакет содержит указатели на набор функций обратного вызова событий, реализованных драйвером. Эти функции обращаются к аппаратным регистрам на устройстве контроллера GPIO. GpioClx вызывает эти функции для обработки запросов ввода-вывода и управления прерываниями.
Драйвер контроллера GPIO вызывает метод GPIO_CLX_UnregisterClient , чтобы отменить регистрацию с помощью GpioClx. Как правило, драйвер вызывает этот метод из функции обратного вызова события EvtDriverUnload .
Инициализация объекта устройства
Чтобы инициализировать GpioClx, драйвер контроллера GPIO должен вызвать два метода GpioClx из функции обратного вызова EvtDriverDeviceAdd . Первый метод, GPIO_CLX_ProcessAddDevicePreDeviceCreate, необходимо вызвать перед вызовом метода WdfDeviceCreate , который создает объект устройства. Второй метод, GPIO_CLX_ProcessAddDevicePostDeviceCreate, должен вызываться после вызова WdfDeviceCreate .
Блокировка прерываний
Большинство функций обратного вызова событий, реализованных драйвером, вызываются только в IRQL = PASSIVE_LEVEL GpioClx. Однако функции обратного вызова в следующем списке вызываются в PASSIVE_LEVEL или DIRQL в зависимости от сведений об устройстве, которые функция обратного вызова CLIENT_QueryControllerBasicInformation предоставляет GpioClx:
- CLIENT_ClearActiveInterrupts
- CLIENT_MaskInterrupts
- CLIENT_QueryActiveInterrupts
- CLIENT_QueryEnabledInterrupts
- CLIENT_UnmaskInterrupt
Эти функции вызываются из подпрограммы обслуживания прерываний (ISR) в GpioClx, которая выполняется в DIRQL или PASSIVE_LEVEL в зависимости от того, сопоставлены ли аппаратные регистры контроллера GPIO в памяти.
Функция CLIENT_QueryControllerBasicInformation предоставляет сведения об устройстве в виде структуры CLIENT_CONTROLLER_BASIC_INFORMATION . Если бит флага MemoryMappedController задан в элементе Flags этой структуры, isR GpioClx вызывает функции обратного вызова из предыдущего списка в DIRQL. В противном случае ISR вызывает все функции обратного вызова, реализованные драйвером в PASSIVE_LEVEL. Дополнительные сведения об этом бите флага см. в разделе Обратные вызовы, связанные с прерыванием.
GpioClx автоматически синхронизирует вызовы с функциями обратного вызова, реализованными драйвером, которые выполняются на PASSIVE_LEVEL и не вызываются из ISR GpioClx. Таким образом, одновременно может выполняться только одна из этих функций. Однако GpioClx не синхронизирует эти PASSIVE_LEVEL обратные вызовы с обратными вызовами, которые GpioClx выполняет из своего ISR. Драйвер контроллера GPIO должен явно предоставить такую синхронизацию, если это необходимо.
Чтобы избежать потенциальных ошибок синхронизации, GpioClx реализует блокировку прерываний , которую драйвер контроллера GPIO может получить и освободить. Блокировка прерываний в основном используется функциями обратного вызова драйвера CLIENT_EnableInterrupt и CLIENT_DisableInterrupt . Драйвер вызывает метод GPIO_CLX_AcquireInterruptLock для получения блокировки и метод GPIO_CLX_ReleaseInterruptLock , чтобы освободить блокировку. Драйвер вызывает эти методы из функции обратного вызова, которая вызывается в PASSIVE_LEVEL и не вызывается из ISR в GpioClx. Хотя драйвер удерживает блокировку, GpioClx ISR не может запуститься. Драйвер должен удерживать блокировку только кратковременно и только во время критических операций, которые должны быть синхронизированы с ISR.
Если GpioClx ISR вызывает функцию обратного вызова, реализованную драйвером, этой функции не нужно получать (или освобождать) блокировку прерывания, так как ISR уже держит блокировку (и отпустит ее). Вызовы методов GPIO_CLX_AcquireInterruptLock и GPIO_CLX_ReleaseInterruptLock этой функцией не оказывают никакого влияния, но не обрабатываются как ошибки.