Een ISR schrijven

Stuurprogramma's voor fysieke apparaten die interrupts genereren, moeten ten minste één interruptserviceroutine (ISR) hebben. De ISR moet alles doen wat geschikt is voor het apparaat om de interrupt te beëindigen, mogelijk inclusief het voorkomen dat het apparaat onderbreekt. Vervolgens moet alleen worden uitgevoerd wat nodig is om de status op te slaan en een DPC in de wachtrij te plaatsen om de I/O-bewerking met een lagere prioriteit (IRQL) te voltooien dan waarop de ISR wordt uitgevoerd.

De ISR van een stuurprogramma wordt uitgevoerd in een interrupt context, op een door het systeem toegewezen DIRQL, zoals opgegeven door de parameter SynchronizeIrql aan IoConnectInterruptEx.

ISR's zijn onderbreekbaar. Een ander apparaat met een hoger door het systeem toegewezen DIRQL kan onderbreken, of een hoge IRQL-systeemonderbreking kan op elk moment plaatsvinden.

Voordat het systeem een ISR aanroept, verkrijgt het de kringvergrendeling van de interrupt, zodat de ISR niet tegelijkertijd kan worden uitgevoerd op een andere processor. Nadat de ISR terugkeert, laat het systeem de spinvergrendeling los.

Omdat een ISR draait op een relatief hoge IRQL, waardoor interrupts worden gemaskeerd met een equivalente of lagere IRQL op de huidige processor, moet deze zo snel mogelijk de besturing teruggeven. Daarnaast beperkt het uitvoeren van een ISR op DIRQL de set ondersteuningsroutines die de ISR kan aanroepen. Zie Hardwareprioriteiten beheren voor meer informatie.

Normaal gesproken voert een ISR de volgende algemene stappen uit:

  • Als het apparaat dat de interrupt heeft veroorzaakt, niet wordt ondersteund door de ISR, retourneert de ISR onmiddellijk ONWAAR.

  • Anders wist de ISR de interrupt indien nodig, slaat de apparaatcontext op en zet een DPC in de wachtrij om de I/O-bewerking bij een lagere IRQL te voltooien. Zie DPC-objecten en DPC's voor meer informatie. De ISR moet vervolgens TRUE retourneren.

In stuurprogramma's die geen I/O-bewerkingen van apparaten overlappen, moet de ISR het volgende doen:

  1. Bepaal of de interrupt oneigenlijk is. Zo ja, retourneer FALSE onmiddellijk zodat de ISR van het apparaat dat de onderbreking veroorzaakte, snel wordt aangeroepen. Anders kunt u doorgaan met onderbreken van de verwerking.

  2. Voorkom dat het apparaat wordt onderbroken, indien nodig.

  3. Verzamel de contextinformatie die de DpcForIsr-routine (of CustomDpc) nodig heeft om de I/O-verwerking voor de huidige bewerking te voltooien.

  4. Sla deze context op in een gebied dat toegankelijk is voor de DpcForIsr - of CustomDpc-routine , meestal in de apparaatextensie van het doelapparaatobject waarvoor de huidige I/O-aanvraag wordt verwerkt, de onderbreking heeft veroorzaakt.

    Als een stuurprogramma I/O-bewerkingen overlapt, moet de contextinformatie een aantal openstaande aanvragen bevatten die de DPC-routine moet voltooien, samen met de context die de DPC-routine nodig heeft om elke aanvraag te voltooien. Als de ISR wordt aangeroepen om een andere interrupt af te handelen voordat de DPC wordt uitgevoerd, mag deze de opgeslagen context niet overschrijven voor een aanvraag die nog niet is voltooid door de DPC.

  5. Als het stuurprogramma een DpcForIsr-routine heeft, roept u IoRequestDpc aan met aanwijzers naar het huidige IRP, het doelapparaatobject en de opgeslagen context. IoRequestDpc zet de DpcForIsr-routine in de wachtrij die moet worden uitgevoerd zodra IRQL onder DISPATCH_LEVEL op een processor valt.

    Als het stuurprogramma een CustomDpc-routine heeft, roept u KeInsertQueueDpc aan met een aanwijzer naar het DPC-object (gekoppeld aan de CustomDpc-routine ) en aanwijzer(s) naar een opgeslagen context die de CustomDpc-routine nodig heeft om de bewerking te voltooien. Meestal geeft de ISR ook de pointers door aan de actuele IRP en het doelapparaat-object. De CustomDpc-routine wordt uitgevoerd zodra IRQL onder DISPATCH_LEVEL op een processor valt.

  6. Retourneer TRUE om aan te geven dat het apparaat de interrupt heeft gegenereerd.

Over het algemeen voert een ISR geen werkelijke I/O-verwerking uit om te voldoen aan een IRP. In plaats daarvan voorkomt het dat zijn apparaat onderbreekt, stelt het de benodigde statusinformatie in en plaatst het de DpcForIsr of CustomDpc van het stuurprogramma in de wachtrij om de benodigde I/O-verwerking uit te voeren die nodig is om te voldoen aan de huidige aanvraag die ervoor zorgde dat het apparaat werd onderbroken.

Een ISR moet worden uitgevoerd met DIRQL voor het kortst mogelijke interval. Volgens deze richtlijn verhoogt u de I/O-doorvoer voor elk apparaat in de machine, omdat het draaien op DIRQL alle onderbrekingen maskeert waaraan het systeem een lagere of gelijke IRQL-waarde heeft toegewezen.

De SyncIrql van de interruptobjecten van het stuurprogramma, opgegeven wanneer het stuurprogramma IoConnectInterrupt heet, bepaalt de DIRQL waarop de ISR van het stuurprogramma wordt uitgevoerd. Zie Toegang tot apparaatgegevens synchroniseren voor meer informatie.