[En-Nut-Discussion] Possible problem with timers

Holger Mai mai at gemac.info
Wed Feb 24 11:56:05 CET 2016


In my view, there is a problem in the last two versions  (5.2 & 5.2.4), that can
cause a hanging Timer.

If the OS is more than 49 days up, then may timers hang.

This is caused by the circumstance, that timers use an 32 bit value in ticks as
time base.

if the tick time is 1ms, then this tick value is equal to milliseconds, and it
overflows after every ~49 days uptime.

if an Timer must run over this borderline of System ticks, it will hang.

To fix this, it is imho the best way, to extend the tick value to 64bit.

this is no problem, since the internal tick counter was fixed to count the ticks
correctly without a 32bit overflow.

the only two things to do are to make two changes in the nut/os/timer.c:

1. add a function that give back the tick count as 64bit:

/*!
 * \brief Return the number of system timer ticks as 64bit value.
 *
 * This function returns the number of system ticks since the system was
 * started.
 *
 * \return Number of ticks.
 */
uint64_t NutGetExtendedTickCount(void)
{
    uint64_t rc;

#ifdef __NUT_EMULATION__
    struct timeval   timeNow;
    gettimeofday( &timeNow, NULL );
    rc = (timeNow.tv_sec - timeStart.tv_sec) * 1000;
    rc += (timeNow.tv_usec - timeStart.tv_usec) / 1000;
#else
#ifndef __CORTEX__
    NutEnterCritical();
    rc = nut_ticks;
    NutExitCritical();
#else
    /* 64bit value readings needs more than one op, therefore encapsulate as
critical section     */
    NutEnterCritical();
    rc = nut_ticks;
    NutExitCritical();
#endif
#endif

    return rc;
}

(also publish this function in the timer.h)

2. two changes in:

void NutTimerProcessElapsed(void)
{
    NUTTIMERINFO *tn;
    uint64_t ticks; //old: 32bit   <-- change tick reference value to 64bit 
    uint32_t ticks_new;

    // calculate ticks since last call
    ticks = NutGetExtendedTickCount(); //old: ticks = NutGetTickCount();  <--
    ticks_new = ticks - nut_ticks_resume;

    ...

}

now a timer is still restricted to a max time of ~49 days (if ticktime is 1ms),
but it cannot hang if it crosses the 49 day uptime border in his runtime.

Outside the timers, the function NutGetMillis() should be extended to give back
a 64 bit result, this is the only way to get correct uptimes > 49 days.

I've made these changes 4 week ago as an OS Patch in my project, but not yet
tested under hard conditions (set the tickcounter to a value of 0xffff f88f or
so and then let the system run over the 49 days border) 

32bit Controllers should have no problem with these changes, on 8bit systems
this costs some more resources, but fixes the problem.

Best regards

Holger Mai

mai at gemac-chemnitz.de

GEMAC - Gesellschaft für Mikroelektronik-
anwendung Chemnitz mbH
Zwickauer Straße 227
D-09116 Chemnitz
Tel. +49 371 3377 - 0
Fax +49 371 3377 272
UST-ID: DE140851265
HRB 6443 Chemnitz/Stadt
Geschäftsführer: Dirk Hübner / Karsten Grönwoldt
http://www.gemac-chemnitz.de

mit freundlichen Grüßen

Holger Mai

mai at gemac-chemnitz.de



GEMAC - Gesellschaft für Mikroelektronik-
anwendung Chemnitz mbH
Zwickauer Straße 227
D-09116 Chemnitz
Tel. +49 371 3377 - 0
Fax +49 371 3377 272
UST-ID: DE140851265
HRB 6443 Chemnitz/Stadt
Geschäftsführer: Dirk Hübner / Karsten Grönwoldt
http://www.gemac-chemnitz.de


More information about the En-Nut-Discussion mailing list