Condividi tramite


Interruzioni dai dispositivi periferici connessi a SPB

A differenza di un bus come PCI, un semplice bus periferico (SPB), ad esempio I2C o SPI, non offre mezzi standard, specifici del bus per trasmettere richieste di interruzione dai dispositivi periferici al processore. Invece, un dispositivo periferico connesso a SPB segnala un interruzione tramite un percorso hardware separato che si trova all'esterno del controller SPB e del controller SPB. I dettagli di questo percorso di interruzione tendono a variare da una piattaforma hardware alla successiva, ma Windows nasconde questi dettagli dal driver per un dispositivo periferica connessa spB per consentire al driver di funzionare in diverse piattaforme hardware.

In genere, la riga di richiesta di interruzione da un dispositivo periferico connesso a SPB è connessa a un pin su un controller di I/O (GPIO) generico e il controller GPIO interrompe gli interruzioni dal dispositivo al processore. Per altre informazioni, vedere Interruzioni GPIO.

Il driver del dispositivo periferico acquisisce questo interruzione GPIO come risorsa di interruzione di Windows astratta (CmResourceTypeInterrupt) e connette l'interruzione alla routine del servizio di interruzione del driver (ISR). L'astrazione della risorsa di interruzione nasconde i dettagli specifici della piattaforma dell'interruzione dal driver. Ad esempio, il driver può ignorare i dettagli, ad esempio se l'interruzione viene ricevuta da un pin GPIO o da un'altra origine. Per mantenere questa astrazione, il gestore di interruzioni del kernel, che viene eseguito in DIRQL, potrebbe dover disattivare una richiesta di interruzione attiva cancellando o mascherando temporaneamente l'interruzione al pin GPIO. I registri hardware del controller GPIO in genere sono mappati alla memoria e possono essere accessibili a DIRQL.

Al contrario, un dispositivo periferico connesso a SPB non è mappato alla memoria e l'ISR per questo dispositivo deve in genere essere eseguito in IRQL = PASSIVE_LEVEL. Per accedere ai registri hardware nel dispositivo, l'ISR invia richieste di I/O per eseguire trasferimenti seriali tramite SPB. Tali trasferimenti sono relativamente lenti e non possono essere eseguiti in un ISR che viene eseguito in DIRQL. Tuttavia, un ISR a livello passivo può inviare una richiesta di I/O in modo sincrono e quindi bloccare fino al completamento della richiesta.

Per un interruzione attivata dal edge, il gestore trap del kernel cancella automaticamente la richiesta di interruzione al pin GPIO e quindi pianifica l'esecuzione dell'ISR del dispositivo a livello passivo. Il gestore trap deve cancellare l'interruzione per impedire che si verifichi nuovamente lo stesso interruzione dopo che il gestore trap restituisce.

Per un interruzione attivata a livello, il gestore del trap di interruzione del kernel maschera automaticamente la richiesta di interruzione al pin GPIO e quindi pianifica l'esecuzione dell'ISR del dispositivo a livello passivo. L'ISR deve cancellare la richiesta di interruzione dal dispositivo. Dopo aver restituito l'ISR, il kernel annulla il maschera della richiesta di interruzione nel pin GPIO.

L'ISR a livello passivo del dispositivo deve eseguire solo la manutenzione iniziale dell'interruzione e quindi tornare a evitare il ritardo delle ISR a livello passivo per altri dispositivi. In genere, il driver deve rinviare l'elaborazione aggiuntiva correlata all'interruzione del thread di lavoro, che viene eseguito con una priorità inferiore rispetto all'ISR.

A partire da Windows 8, il framework di driver in modalità utente (UMDF) supporta gli ISR per i driver UMDF. Il driver UMDF per un dispositivo periferica SPB chiama il metodo IWDFDevice3::CreateInterrupt per connettere un ISR all'interruzione dal dispositivo. Quando il dispositivo segnala una richiesta di interruzione, il gestore trap del kernel pianifica l'esecuzione dell'ISR a livello passivo. Per altre informazioni, vedere Accesso a interruzioni hardware e gestione.

A partire da Windows 8, kernel-mode Driver Framework (KMDF) supporta le ISR a livello passivo. Il driver KMDF per un dispositivo periferica SPB chiama il metodo WdfInterruptCreate per connettere un ISR a livello passivo all'interruzione dal dispositivo. Uno dei parametri di input di questo metodo è un puntatore a una struttura WDF_INTERRUPT_CONFIG che contiene informazioni di configurazione per l'interruzione. Per configurare l'ISR da eseguire a livello passivo, impostare il membro PassiveHandling di questa struttura su TRUE. Per altre informazioni, vedere Supporto di interruzioni Passive-Level.