Udostępnij przez


Rejestrowanie i kolejkowanie procedury CustomTimerDpc

Kierowca może zarejestrować procedurę CustomTimerDpc , wywołując następujące procedury, zwykle z procedury AddDevice :

  1. KeInitializeDpc , aby zarejestrować swoją rutynę

  2. KeInitializeTimer lub KeInitializeTimerEx w celu skonfigurowania obiektu czasomierza

Następnie sterownik może wywołać funkcję KeSetTimer lub KeSetTimerEx , aby określić czas wygaśnięcia i dodać obiekt czasomierza do kolejki czasomierza systemu. Po osiągnięciu czasu wygaśnięcia system usuwa z kolejki obiekt czasomierza i wywołuje procedurę CustomTimerDpc. Na poniższej ilustracji przedstawiono te wywołania.

Diagram ilustrujący używanie obiektów timera i DPC dla niestandardowej procedury TimerDPC.

Jak pokazano na poprzedniej ilustracji, sterownik musi dostarczyć magazyn zarówno dla obiektu DPC, jak i obiektu czasomierza. Większość sterowników zapewnia magazyn dla tych obiektów w rozszerzeniu urządzenia lub w innej pamięci rezydentnej przydzielonej przez sterownik.

W wywołaniu metody KeSetTimer sterownik przekazuje wskaźniki do obiektów Dpc i Timer , wraz z wartością DueTime wyrażoną w jednostkach 100 nanosekund, jak pokazano na poprzedniej ilustracji. Wartość dodatnia dueTime określa bezwzględny czas wygaśnięcia (od 1 stycznia 1601 r.), w którym należy wywołać procedurę CustomTimerDpc . Wartość ujemna dueTime określa względny czas wygaśnięcia.

Ponieważ czasomierz bezwzględny wygasa w określonym czasie systemowym, czas oczekiwania bezwzględnego czasomierza nie ma wpływu, jeśli czas systemowy zmieni się przed wygaśnięciem czasomierza. Z drugiej strony timer względny zawsze wygasa po upływie określonej liczby jednostek czasu, niezależnie od zmian czasu systemowego.

Aby wielokrotnie wywoływać procedurę CustomTimerDpc , użyj polecenia KeSetTimerEx , aby ustawić czasomierz i określić interwał cykliczny w parametrze Okres . KeSetTimerEx jest tak samo jak KeSetTimer z wyjątkiem tego dodatkowego parametru.

Jak pokazano na poprzedniej ilustracji, wywołanie metody KeSetTimer lub KeSetTimerEx kolejkuje obiekt czasomierza dla określonego interwału w następujący sposób:

  1. Po wygaśnięciu właściwości DueTime obiekt czasomierza zostanie usunięty z kolejki i ustawiony na stan zasygnalizowany.

  2. Jeśli każdy procesor w maszynie obecnie wykonuje kod na poziomie IRQL większym lub równym DISPATCH_LEVEL, obiekt DPC skojarzony z obiektem czasomierza jest umieszczany w kolejce DPC. W przeciwnym razie wywoływana jest rutyna CustomTimerDpc .

  3. Jeśli obiekt DPC był już w kolejce, gdy interwał DueTime wygasł, procedura CustomTimerDpc jest wywoływana tak szybko, jak tylko IRQL na dowolnym procesorze w maszynie spadnie poniżej DISPATCH_LEVEL.

    Uwaga

    Rutyna CustomTimerDpc, podobnie jak wszystkie procedury DPC, jest wywoływana na poziomie IRQL = DISPATCH_LEVEL. Podczas wykonywania procedury DPC wszystkie wątki nie mogą działać na tym samym procesorze. Deweloperzy sterowników powinni starannie zaprojektować procedury CustomTimerDpc , aby działały tak krótko, jak to możliwe.

Najmniejszy interwał czasu, jaki można określić dla KeSetTimer i KeSetTimerEx, wynosi około dziesięciu milisekund, więc sterownik może używać procedury CustomTimerDpc, gdy potrzebne są krótsze interwały niż te, które może obsłużyć procedura IoTimer, uruchamiana raz na sekundę.

W dowolnym momencie można dodać do kolejki tylko jedną instancję określonego obiektu czasomierza. Wywołanie ponownie funkcji KeSetTimer lub KeSetTimerEx z tym samym wskaźnikiem obiektu Timer anuluje obiekt Timer znajdujący się w kolejce i resetuje go.

Konfigurowanie procedury CustomTimerDpc jest dokładnie podobne do konfigurowania procedury CustomDpc z dodatkowym krokiem inicjowania obiektu czasomierza. W rzeczywistości ich prototypy są identyczne, ale rutyna CustomTimerDpc nie może używać dwóch wskaźników SystemArgument zadeklarowanych w prototypie.