Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De volgende factoren maken de stuurprogrammacode ingewikkeld die hardwareonderbreken op multiprocessorsystemen afhandelt:
Telkens wanneer een apparaat onderbreekt, levert het interrupt-specifieke informatie die vluchtig is omdat deze de volgende keer dat het apparaat onderbreekt kan worden overschreven.
Apparaten onderbreken op relatief hoge IRQLs en hun interruptserviceroutines (ISR's) kunnen de uitvoering van andere stuurprogrammacode onderbreken.
Voor DIRQL-interrupts moet de ISR op DIRQL draaien terwijl hij een door het stuurprogramma geleverde spinlock vasthoudt, zodat hij extra interrupts kan voorkomen tijdens het opslaan van vluchtige informatie. De DIRQL voorkomt onderbreking door de huidige processor en de spinvergrendeling voorkomt onderbrekingen door een andere processor.
De ISR moet snel worden uitgevoerd omdat het apparaat niet kan onderbreken terwijl de ISR wordt uitgevoerd. Lange ISR-uitvoeringstijden kunnen het systeem vertragen of mogelijk gegevensverlies veroorzaken.
Zowel de ISR- als de DPC-routine (deferred procedure call) moeten doorgaans toegang hebben tot een opslaggebied waarin de ISR de vluchtige gegevens van het apparaat opslaat. Deze routines moeten met elkaar worden gesynchroniseerd, zodat ze niet tegelijkertijd toegang hebben tot het opslaggebied.
Vanwege al deze factoren moet u de volgende regels gebruiken bij het schrijven van stuurprogrammacode die interrupts afhandelt:
Alleen de callback-functie EvtInterruptIsr heeft toegang tot vluchtige interruptgegevens, zoals apparaatregisters die interruptgegevens bevatten.
De callback-functie EvtInterruptIsr moet de vluchtige gegevens verplaatsen naar een door het stuurprogramma gedefinieerde interruptgegevensbuffer die de callback-functie EvtInterruptDpc, de callback-functie EvtInterruptWorkItem, of meerdere EvtDpcFunc callback-functies kunnen openen.
Als uw stuurprogramma evtInterruptDpc of EvtInterruptWorkItem callback-functies biedt voor de interruptobjecten, is de beste plek om interruptgegevens op te slaan de contextruimte van het interruptobject. De callbackfuncties van het interruptobject hebben toegang tot de contextruimte van het object met behulp van de objectgreep die ze ontvangen.
Als uw stuurprogramma meerdere EvtDpcFunc-callbackfuncties biedt voor elke callback-functie EvtInterruptIsr , kunt u onderbrekingsgegevens opslaan in de contextruimte van elk DPC-object.
Alle stuurprogrammacode die toegang heeft tot de interrupt-gegevensbuffer, moet worden gesynchroniseerd, zodat slechts één routine tegelijkertijd toegang heeft tot de gegevens.
Voor DIRQL-interruptobjecten opent de callback-functie EvtInterruptIsr deze gegevensbuffer bij IRQL = DIRQL terwijl de door het stuurprogramma geleverde spinvergrendeling van het interruptobject wordt vastgehouden. Daarom moeten alle routines die toegang hebben tot de buffer ook worden uitgevoerd bij DIRQL terwijl de spinvergrendeling wordt vastgehouden. (Normaal gesproken is de callbackfunctie EvtInterruptDpc of EvtDpcFunc de enige andere routine die toegang moet hebben tot de buffer.)
Alle routines die toegang hebben tot een interrupt-gegevensbuffer, met uitzondering van de callback-functie EvtInterruptIsr , moeten een van de volgende handelingen uitvoeren:
- Roep WdfInterruptSynchronize aan om een EvtInterruptSynchronize callback-functie te plannen die toegang heeft tot de interruptgegevensbuffer.
- Plaats code voor toegang tot de interrupt-gegevensbuffer tussen aanroepen naar WdfInterruptAcquireLock en WdfInterruptReleaseLock.
Met beide technieken kan de functie EvtInterruptDpc of EvtDpcFunc toegang krijgen tot onderbrekingsgegevens op DIRQL-niveau terwijl de spinlock van de interrupt wordt vastgehouden. De DIRQL voorkomt onderbreking door de huidige processor en de spinvergrendeling voorkomt onderbrekingen door een andere processor.
Als uw apparaat ondersteuning biedt voor meerdere interruptvectoren of berichten en als u de verwerking van deze interrupts van uw stuurprogramma wilt synchroniseren, kunt u één kringvergrendeling toewijzen aan meerdere DIRQL-interruptobjecten. Het framework bepaalt de hoogste DIRQL van de set interrupts en verkrijgt altijd de spinlock op die DIRQL, zodat de gesynchroniseerde code niet kan worden onderbroken door onderbrekingsvectoren of berichten in de set.
Voor interruptobjecten op passief niveau verkrijgt het framework de interruptvergrendeling op passiefniveau voordat de callbackfunctie EvtInterruptIsr van het stuurprogramma op IRQL = PASSIVE_LEVEL wordt aangeroepen. Als gevolg hiervan moeten alle routines die toegang hebben tot de buffer de interruptvergrendeling verkrijgen of intern buffertoegang synchroniseren. Normaal gesproken is de callback-functie EvtInterruptWorkItem van de interrupt de enige andere routine die toegang heeft tot de buffer. Zie de sectie Opmerkingen van die pagina voor informatie over het verkrijgen van de interruptvergrendeling van een EvtInterruptWorkItem-callbackfunctie .
U kunt ook de verwerking van meerdere interruptvectoren van uw stuurprogramma synchroniseren door één wachtvergrendeling toe te wijzen aan meerdere passieve onderbrekingsobjecten.
Als een deel van uw code die DIRQL-interrupts verwerkt, moet worden uitgevoerd op IRQL = PASSIVE_LEVEL, kan de callbackfunctie EvtInterruptDpc of EvtDpcFunc een of meer werkitems maken, zodat de code wordt uitgevoerd als evtWorkItem-callbackfuncties .
In KMDF-versies 1.11 en hoger kan het stuurprogramma ook een onderbrekingswerkitem aanvragen door WdfInterruptQueueWorkItemForIsr aan te roepen. (Zoals u weet, kan de callback-functie van een stuurprogramma EvtInterruptIsrWdfInterruptQueueWorkItemForIsr of WdfInterruptQueueDpcForIsr aanroepen, maar niet beide.)
Als het belangrijk is om de callbackfuncties EvtInterruptDpc en EvtDpcFunc van een stuurprogramma met elkaar en met andere callbackfuncties die aan een apparaat zijn gekoppeld te synchroniseren, kan uw stuurprogramma het lid AutomaticSerialization instellen op TRUE in de WDF_INTERRUPT_CONFIG-structuur van de interrupt en de WDF_DPC_CONFIG-structuur van het DPC-object. De bestuurder kan ook framework spin locks gebruiken. (Als u het lid AutomaticSerialization instelt op TRUE , wordt een callback-functie EvtInterruptIsr niet gesynchroniseerd met andere callback-functies. Gebruik WdfInterruptSynchronize of WdfInterruptAcquireLock om een callback-functie EvtInterruptIsr te synchroniseren, zoals eerder in dit onderwerp is beschreven.)
Voor meer informatie over het synchroniseren van stuurprogrammaroutines, zie Synchronisatietechnieken voor Framework-Based Stuurprogramma's.