Usando temporizadores

Este tópico descreve como usar o suporte interno do temporizador da estrutura. Aplica-se a drivers kmdf (Kernel-Mode Driver Framework), bem como a drivers UMDF (User-Mode Driver Framework) a partir da versão 2.

A estrutura fornece um objeto de temporizador que permite que os drivers criem temporizadores. Depois que um driver cria um objeto de temporizador e inicia o relógio do temporizador, a estrutura chama uma função de retorno de chamada fornecida pelo driver após uma quantidade especificada de tempo ter decorrido. Opcionalmente, o driver pode configurar o temporizador para que a estrutura chame a função de retorno de chamada repetidamente, sempre que um período especificado tiver decorrido.

Para criar um objeto de temporizador de estrutura, o driver deve chamar o método WdfTimerCreate . Esse método registra uma função de retorno de chamada EvtTimerFunc e um intervalo de tempo periódico. Se você quiser que a estrutura chame a função de retorno de chamada apenas uma vez, o driver especificará zero para o intervalo de tempo periódico.

Normalmente, você saberá o número de temporizadores que seu driver precisará para cada dispositivo. Portanto, o driver pode criar objetos de temporizador chamando WdfTimerCreate em sua função de retorno de chamada EvtDriverDeviceAdd e pode armazenar identificadores de objeto de temporizador no espaço de contexto de um dispositivo ou objeto de fila.

Para iniciar o temporizador, seu driver chama WdfTimerStart, passando um "tempo de conclusão". A estrutura inicia o relógio do temporizador e chama a função de retorno de chamada EvtTimerFunc quando o tempo especificado tiver decorrido.

Se o driver forneceu um intervalo de tempo periódico quando chamou WdfTimerCreate, o temporizador será chamado de temporizador periódico. O relógio de um temporizador periódico continua a ser executado após o "tempo de conclusão" inicial ter decorrido e a estrutura chama a função de retorno de chamada do driver repetidamente, sempre que o intervalo de tempo periódico tiver decorrido. Os temporizadores periódicos não são iniciados automaticamente. Como temporizadores não periódicos, o driver ainda deve chamar WdfTimerStart depois de criar o temporizador para iniciá-lo pela primeira vez.

Um driver pode chamar WdfTimerStart de sua função de retorno de chamada EvtTimerFunc para reiniciar um temporizador não periódico depois que ele expirar.

Para parar um temporizador, o driver pode chamar WdfTimerStop. Seu driver pode reutilizar temporizadores iniciando-os e parando-os repetidamente.

Quando o driver cria um objeto de temporizador, ele deve especificar um objeto pai. A estrutura interrompe o temporizador e exclui o objeto de temporizador quando o pai é excluído. Para obter o objeto pai de um objeto de temporizador, o driver pode chamar WdfTimerGetParentObject.

Em versões kmdf anteriores à versão 1.9, você não pode usar facilmente objetos de temporizador se quiser que todas as funções de retorno de chamada do driver sejam executadas em IRQL = PASSIVE_LEVEL. A estrutura implementa a função de retorno de chamada EvtTimerFunc do objeto timer como uma DPC (chamada de procedimento adiado) chamada em IRQL = DISPATCH_LEVEL. Portanto, se você quiser que o código de expiração do temporizador seja executado em PASSIVE_LEVEL a função de retorno de chamada EvtTimerFunc deverá enfileirar um item de trabalho executado em PASSIVE_LEVEL.

Nas versões 1.9 e posteriores do KMDF, você pode criar temporizadores de nível passivo, que são temporizadores executados em PASSIVE_LEVEL. Para criar um temporizador de nível passivo, especifique o nível de execução WdfExecutionLevelPassive quando o driver chamar WdfTimerCreate. Como resultado, a estrutura implementa funções de retorno de chamada EvtTimerFunc como itens de trabalho executados em PASSIVE_LEVEL. Observe que os temporizadores de nível passivo não podem ser temporizadores periódicos.

A partir do UMDF versão 2.0, a estrutura implementa as funções de retorno de chamada EvtTimerFunc do objeto timer como threads de trabalho do pool de threads do modo usuário. Como resultado, as funções de retorno de chamada do temporizador de um driver UMDF sempre são executadas em PASSIVE_LEVEL.

Sem temporizadores de ativação

A eficiência de energia do sistema é reduzida por temporizadores que fazem com que o sistema seja retomado de estados de baixa potência. Uma maneira de melhorar a duração da bateria é atrasar operações periódicas não críticas em vez de acordar o sistema. Começando em Windows 8.1, você não pode usar temporizadores de ativação para executar essas operações não críticas em um driver KMDF ou UMDF. Um temporizador sem ativação não ativa o sistema se ele expirar enquanto o sistema estiver em um estado de baixa potência. Em vez disso, a estrutura chama a função de retorno de chamada EvtTimerFunc do driver na próxima vez que o sistema estiver totalmente ativado, estado S0.

Nenhum temporizador de ativação está disponível a partir do KMDF versão 1.13 e UMDF versão 2.0.

Para criar um temporizador sem ativação, defina o membro TolerableDelay de WDF_TIMER_CONFIG como TolerableDelayUnlimited.

Para obter mais informações sobre nenhum temporizador de ativação, consulte No-Wake Timers.

Temporizadores de alta resolução

Os temporizadores de estrutura padrão têm uma precisão que corresponde ao intervalo de escala do relógio do sistema, que é por padrão 15,6 milissegundos. Começando em Windows 8.1, você pode criar temporizadores de alta resolução. Um temporizador de alta resolução tem uma precisão de um milissegundo. Você pode usar um temporizador de alta resolução para uma operação crítica que requer um tempo de expiração preciso e previsível. Como resultado da manutenção frequente necessária, um temporizador de alta resolução pode resultar na diminuição da duração da bateria.

Os temporizadores de alta resolução estão disponíveis apenas para drivers KMDF, começando com KMDF versão 1.13.

Para criar um temporizador de alta resolução, defina o membro UseHighResolutionTimer de WDF_TIMER_CONFIG como WdfTrue e ajuste o valor de Período para a resolução desejada.

A tabela a seguir mostra exemplos de comportamento do temporizador com base em valores diferentes que o driver fornece para Period. Esses exemplos pressupõem que o intervalo de tique do relógio do sistema seja de 15 milissegundos.

Ponto final, em ms Temporizador Padrão Temporizador de alta resolução

10

O temporizador expira entre 0 milissegundos e 25 milissegundos.

O temporizador expira assim que 10 milissegundos possível.

16

O temporizador expira entre 15 milissegundos e 30 milissegundos.

O temporizador expira assim que 16 milissegundos possível.

Para obter mais informações sobre temporizadores de alta resolução, consulte Temporizadores de alta resolução.

Para obter mais informações sobre como a precisão do temporizador está relacionada à granularidade do relógio do sistema, consulte Precisão do temporizador.