Обратные вызовы Interrupt-Related
Как вариант, драйвер для контроллера ввода-вывода общего назначения (GPIO) может обеспечить поддержку прерываний GPIO. Для поддержки прерываний GPIO драйвер контроллера GPIO реализует набор функций обратного вызова для управления этими прерываниями. Драйвер включает указатели на эти функции обратного вызова в пакете регистрации, который драйвер предоставляет при регистрации в качестве клиента расширения платформы GPIO (GpioClx). Дополнительные сведения об этом пакете регистрации см. в разделе GPIO_CLIENT_REGISTRATION_PACKET.
Как правило, контроллер GPIO, который является интегрированной частью микросхемы Системы на микросхеме (SoC), имеет аппаратные регистры, сопоставленные с памятью, к которым процессор в микросхеме SoC может напрямую обращаться. Однако отдельное устройство контроллера GPIO может быть подключено извне к микросхеме SoC через последовательную шину, как показано на следующей схеме.
На этой схеме внешний контроллер GPIO подключен к шине I²C. Эта шина управляется контроллером шины I²C, который является интегрированной частью микросхемы SoC. Строка запроса прерывания от внешнего контроллера GPIO подключается к контакту на интегрированном контроллере GPIO. GpioClx DDI может вместить как интегрированный контроллер GPIO, так и внешний контроллер GPIO в этом примере.
Если устройство контроллера GPIO сопоставлено в памяти, драйвер контроллера GPIO может напрямую обращаться к аппаратным регистрам контроллера в DIRQL. Однако если контроллер GPIO подключен последовательно, драйвер контроллера GPIO может получить доступ к аппаратным регистрам только в irQL = PASSIVE_LEVEL, как описано в разделе IsR пассивного уровня.
Драйвер для контроллера GPIO с аппаратными регистрами, сопоставленными с памятью, должен задать бит флага MemoryMappedController в сведениях об устройстве, которые драйвер предоставляет GpioClx. В противном случае GpioClx предполагает, что аппаратные регистры не сопоставлены с памятью, и драйвер может получить доступ к этим регистрам только в irQL = PASSIVE_LEVEL. Дополнительные сведения об этом бите флага см. в разделе CONTROLLER_ATTRIBUTE_FLAGS.
GpioClx реализует подпрограмму обслуживания прерываний (ISR) для запросов прерываний обслуживания от контроллера GPIO. Этот ISR вызывает следующие функции обратного вызова, связанные с прерыванием:
CLIENT_ClearActiveInterruptsCLIENT_MaskInterruptsCLIENT_QueryActiveInterruptsCLIENT_QueryEnabledInterruptsCLIENT_UnmaskInterrupt Эти функции вызываются в DIRQL или PASSIVE_LEVEL в зависимости от того, выполняется ли ISR в GpioClx в DIRQL или PASSIVE_LEVEL. ISR вызывает эти функции в DIRQL, если MemoryMappedController = 1, и в PASSIVE_LEVEL, если MemoryMappedController = 0. В любом случае ISR автоматически сериализует свои обратные вызовы, чтобы вызов одной из этих функций не происходил в середине вызова другой из этих функций.
Расширение платформы GPIO вызывает следующие функции обратного вызова, связанные с прерыванием, только в PASSIVE_LEVEL, независимо от того, установлен ли флаг MemoryMappedController :
CLIENT_DisableInterruptCLIENT_EnableInterrupt Если флаг MemoryMappedController не установлен, все функции обратного вызова, связанные с прерыванием, вызываются в PASSIVE_LEVEL. GpioClx автоматически сериализует вызовы этих функций, чтобы вызов одной из этих функций не происходил в середине вызова другой из этих функций.
Однако если установлен флаг MemoryMappedController , функции CLIENT_EnableInterrupt и CLIENT_DisableInterrupt должны явно синхронизировать свои операции включения прерываний и отключения с GpioClx ISR, который вызывает другие четыре функции обратного вызова, связанные с прерыванием, в DIRQL.
Как правило, другие функции обратного вызова CLIENT_Xxx (имена которых не содержат "Прерывание") не выполняют обработку, связанную с прерыванием, и, следовательно, не нужно синхронизировать с GpioClx ISR. Однако если какая-либо из этих функций вызывается в PASSIVE_LEVEL и содержит код, который обращается к параметрам прерываний, которые доступны функциям, связанным с прерываниями, в DIRQL, этот код должен быть синхронизирован с ISR.
Для поддержки синхронизации прерываний GpioClx реализует набор блокировок прерываний. Функция обратного вызова, которая выполняется на PASSIVE_LEVEL, может вызвать метод GPIO_CLX_AcquireInterruptLock для получения блокировки прерывания и вызвать метод GPIO_CLX_ReleaseInterruptLock , чтобы освободить блокировку. Если функция удерживает блокировку прерывания, isR GpioClx не может выполняться, и эта функция ISR не может вызывать любую функцию обратного вызова, связанную с прерыванием. Чтобы обеспечить своевременную обработку прерываний GPIO, драйвер должен удерживать блокировку прерываний не дольше, чем это необходимо.
Дополнительные сведения см. в статье Синхронизация прерываний для драйверов контроллера GPIO.