Uso di timer

Questo argomento descrive come usare il supporto timer predefinito del framework. Si applica a entrambi i driver Kernel-Mode Driver Framework (KMDF) e User-Mode Driver Framework (UMDF) a partire dalla versione 2.

Il framework fornisce un oggetto timer che consente ai driver di creare timer. Dopo che un driver crea un oggetto timer e avvia l'orologio del timer, il framework chiama una funzione di callback fornita dal driver dopo un intervallo di tempo specificato. Facoltativamente, il driver può configurare il timer in modo che il framework chiami ripetutamente la funzione di callback, ogni volta che è trascorso un intervallo di tempo specificato.

Per creare un oggetto timer del framework, il driver deve chiamare il metodo WdfTimerCreate . Questo metodo registra una funzione callback EvtTimerFunc e un intervallo di tempo periodico. Se si vuole che il framework chiami la funzione di callback una sola volta, il driver specifica zero per l'intervallo di tempo periodico.

In genere, si conoscerà il numero di timer necessari per ogni dispositivo. Pertanto, il driver può creare oggetti timer chiamando WdfTimerCreate nella sua funzione evtDriverDeviceAdd callback e può archiviare gli handle degli oggetti timer in uno spazio di contesto di un dispositivo o di coda.

Per avviare il timer, il driver chiama WdfTimerStart, passando un "tempo dovuto". Il framework avvia l'orologio del timer e chiama la funzione di callback EvtTimerFunc quando è trascorso il tempo specificato.

Se il driver ha fornito un intervallo di tempo periodico quando si chiama WdfTimerCreate, il timer viene definito timer periodico. L'orologio del timer periodico continua a essere eseguito dopo l'intervallo di tempo "dovuto" iniziale e il framework chiama ripetutamente la funzione di callback del driver, ogni volta che l'intervallo di tempo periodico è trascorso. I timer periodici non vengono avviati automaticamente. Come i timer non periodici, il driver deve comunque chiamare WdfTimerStart dopo aver creato il timer per avviarlo per la prima volta.

Un driver potrebbe chiamare WdfTimerStart dalla sua funzione di callback EvtTimerFunc per riavviare un timer non periodico dopo la scadenza.

Per arrestare un timer, il driver può chiamare WdfTimerStop. Il driver può riutilizzare i timer avviandoli e arrestandoli ripetutamente.

Quando il driver crea un oggetto timer, deve specificare un oggetto padre. Il framework arresta il timer ed elimina l'oggetto timer quando l'elemento padre viene eliminato. Per ottenere un oggetto padre di un oggetto timer, il driver può chiamare WdfTimerGetParentObject.

Nelle versioni kmDF precedenti alla versione 1.9 non è possibile usare facilmente oggetti timer se si desidera che tutte le funzioni di callback del driver vengano eseguite in IRQL = PASSIVE_LEVEL. Il framework implementa la funzione di callback evtTimerFunc dell'oggetto timer come chiamata di procedura posticipata (DPC) chiamata a IRQL = DISPATCH_LEVEL. Pertanto, se si vuole che il codice di scadenza del timer venga eseguito in PASSIVE_LEVEL la funzione di callback EvtTimerFunc deve accodare un elemento di lavoro eseguito in PASSIVE_LEVEL.

Nelle versioni di KMDF 1.9 e versioni successive è possibile creare timer a livello passivo, ovvero timer eseguiti in PASSIVE_LEVEL. Per creare un timer a livello passivo, specificare il livello di esecuzione WdfExecutionLevelPassive quando il driver chiama WdfTimerCreate. Di conseguenza, il framework implementa le funzioni di callback EvtTimerFunc come elementi di lavoro eseguiti in PASSIVE_LEVEL. Si noti che i timer a livello passivo non possono essere timer periodici.

A partire dalla versione 2.0 di UMDF, il framework implementa le funzioni di callback evtTimerFunc dell'oggetto timer come thread di lavoro dal pool di thread in modalità utente. Di conseguenza, le funzioni di callback timer di un driver UMDF vengono eseguite sempre in PASSIVE_LEVEL.

Nessun timer di riattivazione

L'efficienza della potenza del sistema è ridotta dai timer che causano ripetutamente la ripresa del sistema da stati a bassa potenza. Un modo per migliorare la durata della batteria consiste nel ritardare operazioni periodiche non critiche anziché svegliare il sistema. A partire da Windows 8.1, non è possibile usare timer di riattivazione per eseguire operazioni non critiche in un driver KMDF o UMDF. Un timer di riattivazione non riattiva il sistema se scade mentre il sistema è in stato di bassa potenza. Il framework chiama invece la funzione di callback EvtTimerFunc del driver la prossima volta che il sistema si trova completamente in stato S0.

Non sono disponibili timer di riattivazione a partire dalla versione 1.13 e UMDF versione 2.0.

Per creare un timer di riattivazione, impostare il membro TolerableDelay di WDF_TIMER_CONFIG su TolerableDelayUnlimited.

Per altre informazioni su nessun timer di riattivazione, vedere Timer di riattivazione.

Timer ad alta risoluzione

I timer del framework standard hanno un'accuratezza corrispondente all'intervallo di graduazione dell'orologio di sistema, ovvero per impostazione predefinita 15,6 millisecondi. A partire da Windows 8.1, è possibile creare timer ad alta risoluzione. Un timer ad alta risoluzione ha un'accuratezza di un millisecondo. È possibile usare un timer ad alta risoluzione per un'operazione critica che richiede un'ora di scadenza precisa e prevedibile. A causa della frequente manutenzione necessaria, un timer ad alta risoluzione può causare una riduzione della durata della batteria.

I timer a risoluzione elevata sono disponibili solo per i driver KMDF, a partire dalla versione 1.13 di KMDF.

Per creare un timer ad alta risoluzione, impostare il membro UseHighResolutionTimer di WDF_TIMER_CONFIG su WdfTrue e quindi modificare il valore Period sulla risoluzione desiderata.

Nella tabella seguente vengono illustrati esempi di comportamento timer in base a valori diversi forniti dal driver per Period. Questi esempi presuppongono che l'intervallo di graduazione dell'orologio di sistema sia di 15 millisecondi.

Periodo, in ms Standard Timer Timer ad alta risoluzione

10

Il timer scade tra 0 millisecondi e 25 millisecondi.

Il timer scade appena dopo 10 millisecondi possibile.

16

Il timer scade tra 15 millisecondi e 30 millisecondi.

Il timer scade appena dopo 16 millisecondi possibile.

Per altre informazioni sui timer ad alta risoluzione, vedere Timer ad alta risoluzione.

Per altre informazioni sul modo in cui l'accuratezza del timer è correlata alla granularità dell'orologio di sistema, vedere Accuratezza timer.