Поделиться через


Interrupt-Related Обратные вызовы

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

Как правило, контроллер GPIO, который является интегрированной частью микросхемы System on a Chip (SoC), имеет аппаратные регистры, сопоставленные с памятью, которые могут быть напрямую доступны процессором в микросхеме SoC. Однако отдельное устройство контроллера GPIO может быть подключено внешне к микросхеме SoC через последовательную шину, как показано на следующей схеме.

интегрированный контроллер gpio и внешний контроллер gpio.

На этой схеме внешний контроллер GPIO подключен к шине I²C. Эта шина управляется контроллером шины IІC, который является интегрированной частью микросхемы SoC. Линия запроса прерывания от внешнего контроллера GPIO подключена к контакту на встроенном контроллере GPIO. DDI GpioClx может разместить как интегрированный контроллер GPIO, так и внешний контроллер GPIO в этом примере.

Если устройство контроллера GPIO отображено в памяти, драйвер контроллера GPIO может напрямую получить доступ к аппаратным регистрам контроллера на DIRQL. Однако если контроллер GPIO подключен последовательно, драйвер этого контроллера может обращаться к аппаратным регистрам только при IRQL = PASSIVE_LEVEL, как указано в 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 должны явно синхронизировать свои операции включения и отключения прерываний с ISR GpioClx, которая вызывает другие четыре функции обратного вызова, связанные с прерыванием, на уровне DIRQL.

Как правило, другие функции обратного вызова CLIENT_Xxx (имена которых не содержат "Interrupt") не занимаются обработкой прерываний и поэтому не требуют синхронизации с ISR GpioClx. Однако если любая из этих функций вызывается в PASSIVE_LEVEL и содержит код, который обращается к параметрам прерывания, доступ к которым осуществляется функциями, связанными с прерыванием в DIRQL, этот код должен быть синхронизирован с ISR.

Для поддержки синхронизации прерываний GpioClx реализует набор блокировок прерываний. Функция обратного вызова, которая выполняется в PASSIVE_LEVEL, может вызывать метод GPIO_CLX_AcquireInterruptLock для получения блокировки прерывания и вызова метода GPIO_CLX_ReleaseInterruptLock для освобождения блокировки. Если функция содержит блокировку прерывания, ISR GpioClx не может выполняться, и этот ISR не может вызывать никакую функцию обратного вызова, связанную с прерываниями. Чтобы обеспечить своевременную обработку прерываний GPIO, драйвер должен держать блокировку прерываний не дольше, чем необходимо.

Дополнительные сведения см. в разделе Синхронизация прерываний для драйверов контроллеров GPIO.