Прерывания от периферийных устройств, подключенных к SPB
В отличие от шин, таких как PCI, простая периферийная шина (SPB), например I2C или SPI, не предоставляет стандартизированных средств передачи запросов прерываний от периферийных устройств к процессору. Вместо этого периферийное устройство, подключенное к SPB, сигнализирует о прерывании через отдельный аппаратный путь, который находится за пределами контроллера SPB и SPB. Сведения об этом пути прерывания, как правило, различаются на разных аппаратных платформах, но Windows скрывает эти сведения от драйвера для периферийного устройства, подключенного к SPB, чтобы драйвер мог работать на различных аппаратных платформах.
Как правило, строка запроса прерывания с периферийного устройства, подключенного к SPB, подключается к контакту на контроллере ввода-вывода общего назначения (GPIO), а контроллер GPIO передает прерывания от устройства к процессору. Дополнительные сведения см. в разделе Прерывания GPIO.
Драйвер периферийного устройства получает это прерывание GPIO как абстрактный ресурс прерываний Windows (CmResourceTypeInterrupt) и подключает прерывание к подпрограмме службы прерываний драйвера (ISR). Абстракция ресурса прерывания скрывает от драйвера сведения о прерывании для конкретной платформы. Например, драйвер может игнорировать такие сведения, как получение прерывания от контакта GPIO или из другого источника. Чтобы сохранить эту абстракцию, обработчику перехвата прерываний ядра, который выполняется в DIRQL, может потребоваться заглушить активный запрос прерывания путем очистки или временного маскирования прерывания в контакте GPIO. Аппаратные регистры контроллера GPIO обычно сопоставляются в памяти и доступны в DIRQL.
В отличие от этого, подключенное к SPB периферийное устройство не сопоставлено в памяти, и ISR для этого устройства обычно должен выполняться в irQL = PASSIVE_LEVEL. Для доступа к аппаратным регистрам на устройстве ISR отправляет запросы ввода-вывода для выполнения последовательной передачи через SPB. Такие передачи выполняются относительно медленно и не могут выполняться в ISR, который выполняется в DIRQL. Однако ISR пассивного уровня может отправлять запрос ввода-вывода синхронно, а затем блокировать, пока запрос не завершится.
Для прерывания, активированного ребром, обработчик ловушки ядра автоматически очищает запрос прерывания в контакте GPIO, а затем планирует запуск ISR устройства на пассивном уровне. Обработчик ловушки должен очистить прерывание, чтобы предотвратить повторное прерывание после возврата обработчика ловушки.
Для прерывания, активированного на уровне, обработчик перехвата прерываний ядра автоматически маскирует запрос прерывания в контакте GPIO, а затем планирует запуск ISR устройства на пассивном уровне. ISR должен очистить запрос прерывания от устройства. После возврата ISR ядро расмаскивает запрос прерывания в контакте GPIO.
IsR пассивного уровня устройства должен выполнять только начальное обслуживание прерывания, а затем вернуться, чтобы избежать задержки ISR пассивного уровня для других устройств. Как правило, драйвер должен отложить дополнительную обработку, связанную с прерываниями, в рабочий поток прерывания, который выполняется с более низким приоритетом, чем ISR.
Начиная с Windows 8, среда выполнения платформы драйвера режима пользователя (UMDF) поддерживает ISR для драйверов UMDF. Драйвер UMDF для периферийного устройства SPB вызывает метод IWDFDevice3::CreateInterrupt для подключения ISR к прерыванию с устройства. Когда устройство отправляет запрос на прерывание, обработчик ловушки ядра планирует выполнение ISR на пассивном уровне. Дополнительные сведения см. в разделе Доступ к оборудованию и обработка прерываний.
Начиная с Windows 8, платформа драйвера в режиме ядра (KMDF) поддерживает isR пассивного уровня. Драйвер KMDF для периферийного устройства SPB вызывает метод WdfInterruptCreate для подключения ISR пассивного уровня к прерыванию с устройства. Одним из входных параметров этого метода является указатель на структуру WDF_INTERRUPT_CONFIG , содержащую сведения о конфигурации для прерывания. Чтобы настроить isR для запуска на пассивном уровне, задайте для элемента PassiveHandling этой структуры значение TRUE. Дополнительные сведения см. в разделе Поддержка прерываний Passive-Level.