timer

Vous pouvez aussi avoir un traitement cyclique ou déclenché à une date donnée en déclarant une dpc timer utilisant le timer disponible au niveau driver.

Une date peut être spécifiée en unité de 100 ns et une période en ms. Dans la pratique on constate une résolution de 10 ms. La cadence maximale est donc de 100 hz sauf si vous avez déclaré quelque part un multimédia timer ce qui vous permet alors mystérieusement de monter à 1000 hz.

//
// dpc accrochée au timer
//
VOID
DPCtimer(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
);

Installer une dpc timer

 

unsigned long SetDpcTimer(unsigned long newPeriodeMs)
{
    _LARGE_INTEGER next;
    unsigned long unite100ns,uniteMs;
    // double integer, fraction, rapport;
    if(!DeviceTimerInstalled)
    {
        KeInitializeTimerEx(&DeviceTimer,SynchronizationTimer);
        KeInitializeDpc(&DeviceDPCTimer,DPCtimer,DeviceObject);
        DeviceTimerInstalled = true;
        PC_timer_resolution_ms = 0;
        }
        // demande de l'unite en principe en 100ns
        unite100ns = KeQueryTimeIncrement();
        // arrondir cette unite en ms en principe 10 ms
        uniteMs = (unite100ns+5000)/10000;
        // précaution si on tombe sur des systèmes inférieurs à la ms
        if(uniteMs==0)
            uniteMs = 1;
        // pour avoir un système régulier prendre le multiple le plus proche
        newPeriodeMs = newPeriodeMs / uniteMs * uniteMs; 
        if(newPeriodeMs<uniteMs)
            newPeriodeMs = uniteMs;
        if(newPeriodeMs==0)
            newPeriodeMs = 1;
        // changer l'intervalle
        if(newPeriodeMs!=PC_timer_resolution_ms)
        {
            next.QuadPart = -10;
            PC_timer_resolution_ms = newPeriodeMs;
            DbgPrint("cycle %d ms,unite timer=%d us\n",PC_timer_resolution_ms,unite100ns/10);
            KeSetTimerEx(&DeviceTimer,
                    next, // activation dans 10*100ns
            PC_timer_resolution_ms, // periode en ms
            &DeviceDPCTimer);
            // les messages seront placés en tête de file de dpc
            KeSetImportanceDpc (&DeviceDPCTimer,HighImportance);
        }
        return PC_timer_resolution_ms;
    }

Désinstaller


// annulation du timer
void ResetDpcTimer(void)
{
    KeCancelTimer(&DeviceTimer);
    DeviceTimerInstalled = false;
}

Accueil ] Remonter ]