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


Обслуживание прерывания

В этом разделе описывается, как обслуживать прерывание DIRQL. Сведения о обслуживании прерывания пассивного уровня см. в поддержке прерываний пассивного уровня.

Обслуживание прерывания состоит из двух, а иногда и трех этапов:

  1. Быстрое сохранение изменчивых данных (например, содержимого регистра) в обработчике прерываний, который выполняется на уровне IRQL = DIRQL.

  2. Обработка сохраненной изменчивой информации в вызове отложенной процедуры (DPC), который выполняется на уровне IRQL = DISPATCH_LEVEL.

  3. При необходимости выполняйте дополнительную работу на уровне IRQL = PASSIVE_LEVEL.

Когда устройство создает аппаратное прерывание, фреймворк вызывает подпрограмму обработки прерываний драйвера (ISR), которую драйверы на основе фреймворка реализуют как функцию обратного вызова EvtInterruptIsr.

Функция обратного вызова EvtInterruptIsr, которая выполняется на DIRQL устройства, должна быстро сохранять сведения о прерывании, такие как содержимое регистра, которое будет потеряно при возникновении другого прерывания.

Как правило, функция обратного вызова EvtInterruptIsr планирует отложенный вызов процедуры (DPC) для последующей обработки сохраненных сведений в более низком уровне IRQL (DISPATCH_LEVEL). Драйверы, основанные на каркасе, реализуют подпрограммы DPC как функции обратного вызова EvtInterruptDpc или EvtDpcFunc.

Большинство драйверов используют одну функцию обратного вызова EvtInterruptDpc для каждого типа прерывания. Чтобы запланировать выполнение функции обратного вызова EvtInterruptDpc, драйвер должен вызвать WdfInterruptQueueDpcForIsr из функции обратного вызова EvtInterruptIsr.

Если ваш драйвер создает несколько объектов очереди для каждого устройства, вы можете рассмотреть возможность использования отдельного объекта DPC и функции обратного вызова EvtDpcFunc для каждой очереди. Чтобы запланировать выполнение функции обратного вызова EvtDpcFunc, драйвер должен сначала создать один или несколько объектов DPC, вызвав WdfDpcCreate, обычно в функции обратного вызова драйвера EvtDriverDeviceAdd. Затем функция обратного вызова EvtInterruptIsr драйвера может вызывать WdfDpcEnqueue.

Драйверы обычно выполняют запросы ввода-вывода в функциях обратного вызова EvtInterruptDpc или EvtDpcFunc.

Иногда драйвер должен выполнять операции обслуживания прерываний на уровне IRQL = PASSIVE_LEVEL. В таких случаях функция обратного вызова драйвера EvtInterruptDpc или EvtDpcFunc, выполняемая на уровне IRQL = DISPATCH_LEVEL, может запланировать выполнение одного или нескольких рабочих элементов платформы , которые выполняются на уровне IRQL = PASSIVE_LEVEL.

Пример драйвера, использующего рабочие элементы при обработке прерываний устройства, см. в образце драйвера PCIDRV.