Использование подпрограмм службы прерывания Passive-Level

Начиная с Windows 8, драйвер может использовать подпрограмму IoConnectInterruptEx для регистрации подпрограммы Прерывания Службы пассивного уровня (ISR). Когда происходит связанное прерывание, обработчик перехвата прерываний ядра планирует выполнение этой подпрограммы в IRQL = PASSIVE_LEVEL. IsR может потребоваться запустить на пассивном уровне, если он может получить доступ к аппаратным регистрам устройства только через запросы ввода-вывода. ISR пассивного уровня может синхронно отправлять запрос ввода-вывода на устройство и блокировать его до завершения запроса.

Регистрация Passive-Level ISR

Входной параметр IoConnectInterruptEx является указателем на структуру IO_CONNECT_INTERRUPT_PARAMETERS . Чтобы зарегистрировать ISR пассивного уровня, задайте для элемента Version этой структуры значение CONNECT_FULLY_SPECIFIED или CONNECT_LINE_BASED. Если Version = CONNECT_FULLY_SPECIFIED, задайте для элемента Irql значение PASSIVE_LEVEL, для элемента SynchronizeIrql — PASSIVE_LEVEL, а для элемента SpinLockзначение NULL. Если Version = CONNECT_LINE_BASED, задайте значение SynchronizeIrql = PASSIVE_LEVEL и SpinLock = NULL.

Если объект прерывания задает ISR пассивного уровня, подпрограмма KeSynchronizeExecution использует объект события синхронизации ядра вместо блокировки спина для синхронизации выполнения подпрограммы SynchCritSection с ISR.

Этот объект события выделяется подпрограммой IoConnectInterruptEx в вызове, который регистрирует ISR пассивного уровня. Вызывающий объект не должен предоставлять блокировку спина в этом вызове. (То есть вызывающий объект должен задать элемент SpinLock структуры IO_CONNECT_INTERRUPT_PARAMETERS значение NULL, если ISR должен выполняться на пассивном уровне.) В противном случае IoConnectInterruptEx завершается сбоем и возвращает состояние ошибки STATUS_INVALID_PARAMETER.

Подпрограммы KeAcquireInterruptSpinLock и KeReleaseInterruptSpinLock вызывают ошибку проверка, если ISR для предоставленного объекта прерывания выполняется в IRQL = PASSIVE_LEVEL.

Устройства, требующие обработки прерываний Passive-Level

Для сопоставленного в памяти устройства, которое сигнализирует о запросе на прерывание уровня, ISR устройства обычно вызывается в DIRQL из обработчика перехвата прерываний ядра. ISR управляет аппаратными регистрами на устройстве, чтобы отключить прерывание.

Однако isR может потребоваться выполнить по адресу IRQL = PASSIVE_LEVEL, если связанное устройство сигнализирует об инициированном на уровне запросе прерывания, но аппаратные регистры устройства не могут быть доступны напрямую из ISR, вызываемого в DIRQL из обработчика перехвата прерываний ядра. Например, регистры устройств могут быть не сопоставлены с памятью, или ISR может быть временно заблокирован во время регистрации доступа.

Начиная с Windows 8 драйвер может зарегистрировать ISR пассивного уровня. Когда происходит прерывание, обработчик перехвата прерываний ядра планирует запуск ISR в IRQL = PASSIVE_LEVEL. Перед возвратом обработчик должен заглушить прерывание в контроллере прерываний (или контроллере GPIO). Если устройство сигнализирует о прерывании, инициируемом ребром, обработчик очищает прерывание в контроллере прерываний. Если устройство сигнализирует об прерывании с активацией уровня, обработчик временно маскирует прерывание в контроллере прерывания; после выполнения ISR ядро распаковывает прерывание.

Пример

Примером устройства, которому может потребоваться ISR пассивного уровня, является устройство датчика, подключенное к маломощной последовательной шине, например I²C. Начиная с Windows 8, поддержка I²C и других простых периферийных шин (SPB) обеспечивается расширением платформы SPB (SpbCx).

Чтобы получить доступ к регистрам устройства датчика, подключенного к I²C, драйвер датчика отправляет устройству датчика запрос ввода-вывода, который совместно обрабатывается SpbCx и драйвером контроллера для шины. Чтобы выполнить запрошенную операцию, контроллер SPB должен последовательно передавать данные по шине. Эта передача выполняется относительно медленно и не может быть выполнена в течение ограничений времени ISR, работающих в DIRQL. Однако ISR пассивного уровня может отправлять запрос ввода-вывода синхронно, а затем блокировать до завершения запроса.

IsR пассивного уровня в этом примере может быть заблокирован на более длительное время, если контроллер шины I²C отключен, когда ISR отправляет запрос ввода-вывода на прерывающее устройство. В этом случае контроллер должен завершить переход в состояние питания D0, прежде чем сможет передавать данные по шине.

В отличие от шин, таких как PCI, шина I²C в этом примере не предоставляет специальных средств для передачи запросов прерываний от периферийных устройств к процессору. Вместо этого устройство датчика может сигнализировать о прерывании на закреплении на устройстве контроллера GPIO, который затем передает запрос на прерывание процессору. Дополнительные сведения см. в разделе Прерывания GPIO.

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

Для прерывания с активацией уровня обработчик перехвата прерываний ядра маскирует запрос прерывания в контакте GPIO, а затем планирует запуск ISR устройства датчика на пассивном уровне. ISR должен очистить запрос прерывания от устройства датчика. После возврата ISR ядро распаковывает запрос прерывания в контакте GPIO.

Для прерывания, активированного ребром, обработчик ловушки ядра очищает запрос прерывания в контакте GPIO, а затем планирует запуск ISR устройства датчика на пассивном уровне.

Рабочие подпрограммы

При вызове IoConnectInterruptEx драйвер может разделить обработку прерывания между ISR пассивного уровня и рабочей подпрограммой. Как правило, ISR должен выполнять начальную обработку прерывания (например, заглушить прерывание с активацией уровня) и отложить дополнительную обработку для рабочей роли. Хотя и ISR, и рабочая роль выполняются на пассивном уровне, ISR выполняется с относительно высоким приоритетом и может отложить другие высокоприоритетные задачи. Эти задачи могут включать ВС пассивного уровня для новых прерываний.

В редких случаях прерывание может требовать настолько мало обработки, что ISR пассивного уровня может выполнить всю обработку прерывания, и не требуется никаких рабочих процедур.

Сведения об использовании isR пассивного уровня в драйверах KMDF см. в разделе Поддержка прерываний Passive-Level.