Interrupciones de dispositivos periféricos conectados a SPB
A diferencia de un bus como PCI, un bus periférico simple (SPB), como I2C o SPI, no proporciona medios estandarizados específicos de bus para transmitir solicitudes de interrupción de dispositivos periféricos al procesador. En su lugar, un dispositivo periférico conectado a SPB señala una interrupción a través de una ruta de acceso de hardware independiente que se encuentra fuera del SPB y del controlador SPB. Los detalles de esta ruta de interrupción tienden a variar de una plataforma de hardware a la siguiente, pero Windows oculta estos detalles del controlador para un dispositivo periférico conectado a SPB para permitir que el controlador funcione en una variedad de plataformas de hardware.
Normalmente, la línea de solicitud de interrupción de un dispositivo periférico conectado a SPB está conectada a un pin en un controlador de E/S de uso general (GPIO) y el controlador GPIO retransmite interrupciones desde el dispositivo al procesador. Para obtener más información, consulte Interrupciones de GPIO.
El controlador de dispositivo periférico adquiere esta interrupción GPIO como un recurso de interrupción abstracto de Windows (CmResourceTypeInterrupt) y conecta la interrupción a la rutina de servicio de interrupción del controlador (ISR). La abstracción de recursos de interrupción oculta los detalles específicos de la plataforma de la interrupción del controlador. Por ejemplo, el controlador puede omitir los detalles, como si la interrupción se recibe de un pin GPIO o de algún otro origen. Para mantener esta abstracción, el controlador de captura de interrupciones del kernel, que se ejecuta en DIRQL, puede que tenga que silenciar una solicitud de interrupción activa borrando o enmascarando temporalmente la interrupción en el pin GPIO. Normalmente, los registros de hardware del controlador GPIO están asignados a memoria y se puede acceder a ellos en DIRQL.
Por el contrario, un dispositivo periférico conectado a SPB no está asignado a memoria y el ISR para este dispositivo normalmente debe ejecutarse en IRQL = PASSIVE_LEVEL. Para acceder a los registros de hardware en el dispositivo, el ISR envía solicitudes de E/S para realizar transferencias serie a través del SPB. Estas transferencias son relativamente lentas y no se pueden realizar en un ISR que se ejecuta en DIRQL. Sin embargo, un ISR de nivel pasivo puede enviar una solicitud de E/S de forma sincrónica y, a continuación, bloquear hasta que se complete la solicitud.
Para una interrupción desencadenada por el borde, el controlador de capturas del kernel borra automáticamente la solicitud de interrupción en el pin GPIO y, a continuación, programa el ISR del dispositivo para que se ejecute en el nivel pasivo. El controlador de captura debe borrar la interrupción para evitar que se produzca la misma interrupción de nuevo después de que el controlador de captura vuelva.
Para una interrupción desencadenada por el nivel, el controlador de captura de interrupciones del kernel enmascara automáticamente la solicitud de interrupción en el pin GPIO y, a continuación, programa el ISR del dispositivo para que se ejecute en el nivel pasivo. El ISR debe borrar la solicitud de interrupción del dispositivo. Después de que el ISR vuelva, el kernel desmascara la solicitud de interrupción en el pin GPIO.
El ISR de nivel pasivo del dispositivo solo debe realizar el mantenimiento inicial de la interrupción y, a continuación, volver para evitar retrasar los ISR de nivel pasivo para otros dispositivos. Normalmente, el controlador debe aplazar el procesamiento adicional relacionado con la interrupción al subproceso de trabajo de interrupción, que se ejecuta con una prioridad menor que el ISR.
A partir de Windows 8, el marco de controladores del modo de usuario (UMDF) admite ISR para controladores UMDF. El controlador UMDF de un dispositivo periférico SPB llama al método IWDFDevice3::CreateInterrupt para conectar un ISR a la interrupción desde el dispositivo. Cuando el dispositivo señala una solicitud de interrupción, el controlador de capturas del kernel programa el ISR para que se ejecute en el nivel pasivo. Para obtener más información, consulte Acceso a hardware y control de interrupciones.
A partir de Windows 8, el marco de controladores en modo kernel (KMDF) admite ISR de nivel pasivo. El controlador KMDF de un dispositivo periférico SPB llama al método WdfInterruptCreate para conectar un ISR de nivel pasivo a la interrupción del dispositivo. Uno de los parámetros de entrada de este método es un puntero a una estructura de WDF_INTERRUPT_CONFIG que contiene información de configuración para la interrupción. Para configurar el ISR para que se ejecute en el nivel pasivo, establezca el miembro PassiveHandling de esta estructura en TRUE. Para obtener más información, consulte Compatibilidad con interrupciones de Passive-Level.