Compartir a través de


Uso de rutinas de servicio de interrupción de nivel pasivo

A partir de Windows 8, un controlador puede usar la rutina IoConnectInterruptEx para registrar una rutina InterruptService de nivel pasivo (ISR). Cuando se produce la interrupción asociada, el controlador de captura de interrupciones del kernel programa esta rutina para ejecutarse en IRQL = PASSIVE_LEVEL. Es posible que un ISR tenga que ejecutarse en el nivel pasivo si puede acceder a los registros de hardware de un dispositivo solo a través de solicitudes de E/S. Un ISR de nivel pasivo puede enviar sincrónicamente una solicitud de E/S a un dispositivo y bloquear hasta que se complete la solicitud.

Registro de un ISR de nivel pasivo

El parámetro de entrada para IoConnectInterruptEx es un puntero a una estructura IO_CONNECT_INTERRUPT_PARAMETERS. Para registrar un ISR de nivel pasivo, establezca el miembro Version de esta estructura en CONNECT_FULLY_SPECIFIED o CONNECT_LINE_BASED. Si Version = CONNECT_FULLY_SPECIFIED, establezca el miembro Irql en PASSIVE_LEVEL, el miembro SynchronizeIrql en PASSIVE_LEVEL y el miembro SpinLock en NULL. Si Version = CONNECT_LINE_BASED, establezca SynchronizeIrql = PASSIVE_LEVEL y SpinLock = NULL.

Si el objeto de interrupción especifica un ISR de nivel pasivo, la rutina KeSynchronizeExecution usa un objeto de evento de sincronización del kernel en lugar de un bloqueo por subproceso para sincronizar la ejecución de la rutina SynchCritSection con el ISR.

La rutina IoConnectInterruptEx asigna este objeto de evento en la llamada que registra el ISR de nivel pasivo. El llamador no debe proporcionar un bloqueo por subproceso en esta llamada. (Es decir, el llamador debe establecer el miembro SpinLock de la estructura IO_CONNECT_INTERRUPT_PARAMETERS en NULL si el ISR se va a ejecutar en el nivel pasivo). De lo contrario, IoConnectInterruptEx falla y devuelve el estado de error STATUS_INVALID_PARAMETER.

Las rutinas KeAcquireInterruptSpinLock y KeReleaseInterruptSpinLock provocan una comprobación de errores si el ISR del objeto de interrupción proporcionado se ejecuta en IRQL = PASSIVE_LEVEL.

Dispositivos que requieren control de interrupciones de nivel pasivo

Para un dispositivo asignado a memoria que señala una solicitud de interrupción desencadenada por el nivel, el ISR del dispositivo se suele llamar en DIRQL desde el controlador de captura de interrupciones del kernel. El ISR manipula los registros de hardware en el dispositivo para desactivar la interrupción.

Sin embargo, es posible que un ISR tenga que ejecutarse en IRQL = PASSIVE_LEVEL si el dispositivo asociado señala una solicitud de interrupción desencadenada por el nivel, pero no se puede acceder a los registros de hardware del dispositivo directamente desde un ISR que se llama a en DIRQL desde el controlador de captura de interrupciones del kernel. Por ejemplo, es posible que los registros de dispositivos no estén asignados a la memoria o que el ISR se bloquee temporalmente durante un acceso de registro.

A partir de Windows 8, un controlador puede registrar un ISR de nivel pasivo. Cuando se produce la interrupción, el controlador de captura de interrupciones del kernel programa el ISR para que se ejecute en IRQL = PASSIVE_LEVEL. Antes de que el controlador vuelva, debe silenciar la interrupción en el controlador de interrupción (o controlador GPIO). Si un dispositivo señala una interrupción desencadenada por el borde, el controlador borra la interrupción en el controlador de interrupción. Si el dispositivo señala una interrupción desencadenada por el nivel, el controlador enmascara temporalmente la interrupción en el controlador de interrupción; después de que se ejecute el ISR, el kernel desenmascara la interrupción.

Un ejemplo

Un ejemplo de un dispositivo que podría requerir un ISR de nivel pasivo es un dispositivo de sensor que está conectado a un bus serie de baja potencia, como I²C. A partir de Windows 8, la extensión de marco SPB (SpbCx) proporciona compatibilidad con I²C y para otros buses periféricos simples (SPB).

Para acceder a los registros del dispositivo del sensor conectado a I²C, el controlador del sensor envía al dispositivo de sensor una solicitud de E/S, que se controla conjuntamente por SpbCx y por el controlador del controlador para el bus. Para realizar la operación solicitada, el controlador SPB debe transferir datos en serie a través del bus. Esta transferencia es relativamente lenta y no se puede realizar dentro de las restricciones de tiempo de un ISR que se ejecuta en DIRQL. Sin embargo, un ISR de nivel pasivo puede enviar la solicitud de E/S de forma sincrónica y, a continuación, bloquear hasta que se complete la solicitud.

El ISR de nivel pasivo de este ejemplo podría bloquearse durante más tiempo si el controlador de bus I²C está desactivado cuando el ISR envía la solicitud de E/S al dispositivo de interrupción. En este caso, el controlador debe completar la transición al estado de alimentación D0 para poder transferir los datos a través del bus.

A diferencia de un bus como PCI, el bus I²C de este ejemplo no proporciona ningún medio específico de bus para transmitir solicitudes de interrupción de dispositivos periféricos al procesador. En su lugar, el dispositivo del sensor podría indicar una interrupción a una patilla en un dispositivo de controlador GPIO, que luego retransmite la solicitud de interrupción al procesador. Para obtener más información, consulte Interrupciones de GPIO.

Normalmente, los registros de hardware de un controlador GPIO están asignados a la memoria y se puede acceder a ellos en DIRQL mediante el controlador de captura de interrupciones del kernel. Cuando el dispositivo del sensor provoca una interrupción, el controlador debe silenciar la interrupción manipulando los bits de interrupción en los registros del controlador GPIO.

Para una interrupción desencadenada por el nivel, el controlador de captura de interrupciones del kernel enmascara la solicitud de interrupción en el pin GPIO y, a continuación, programa el ISR del dispositivo del sensor para que se ejecute en el nivel pasivo. El ISR debe borrar la solicitud de interrupción del dispositivo del sensor. Después de que el ISR vuelva, el kernel desenmascara la solicitud de interrupción en el pin GPIO.

Para una interrupción desencadenada por el borde, el controlador de captura del kernel borra la solicitud de interrupción en el pin GPIO y, a continuación, programa el ISR del dispositivo del sensor para que se ejecute en el nivel pasivo.

Rutinas de trabajo

En la llamada a IoConnectInterruptEx, un controlador tiene la opción de dividir el procesamiento de la interrupción entre un ISR de nivel pasivo y una rutina de trabajo. Como regla general, el ISR debe realizar el procesamiento inicial de la interrupción (por ejemplo, silenciar una interrupción desencadenada por el nivel) y aplazar el procesamiento adicional al trabajo. Aunque tanto el ISR como el trabajo se ejecutan en el nivel pasivo, el ISR se ejecuta con una prioridad relativamente alta y podría retrasar otras tareas de alta prioridad. Estas tareas pueden incluir ISR de nivel pasivo para nuevas interrupciones.

En raras ocasiones, una interrupción puede requerir un procesamiento tan pequeño que el ISR de nivel pasivo puede realizar todo el procesamiento de la interrupción y no se requiere ninguna rutina de trabajo.

Para obtener información sobre el uso de ISR de nivel pasivo en controladores KMDF, consulte Compatibilidad con interrupciones de nivel pasivo.