[En-Nut-Discussion] Major change in the system clock implementation

Ole Reinhardt ole.reinhardt at embedded-it.de
Thu Aug 15 22:26:32 CEST 2013

Hi All!

I just checked in a major change on the system time API. This change may
affect existing application and needs attention when implementing new

Most important: The system clock is no longer synchronised automatically
with the RTC.

What is the need for the new API?

The old way of calculating the current time was based on the system tick
counter. Unfortunately this introduced bugs when this counter value

On most systems (with 1Khz system tick timer) this happened after 49,7
days. If the system used an RTC, this bug did not show up in most cases,
as the time was then queried from the RTC.

On all systems _without_ an RTC the system tick counter overflows after
49,7 days and the system clock jumps back to 0!

This bug inherits further bugs, which had been reported in the past

Another problem was, that the time could not be corrected with an
accuracy of more than 1 second, as the offset to epoc was calculated as
a value of second resolution.

What's new?

The new time API re-invented the way the time is handled and calculated.

Internally the time is now stored as a timeval struct, which allows a
a clock resolution of up to 1 µs.

The clock is now always updated by the system tick timer interrupt. It
is _not_ automatically synced with the RTC any more. Syncing with a RTC
to be done manually by the user!

This way, we gain a much higher accuracy, as long, as the software clock
is accurate. In other words, the time depends on the system crystal
acint gettimeofday (struct timeval *tv, struct timezone *tz)curacy and
time will not be updated, if the CPU is put to deep sleep mode.

Further more we assume a system tick timer running at a multiple of a
full µs. Uneven system tick timer frequencies will result in an
increasing error of the software clock.

The new API also introduces several new function:


int gettimeofday (struct timeval *tv, struct timezone *tz);
int settimeofday (struct timeval *tv, struct timezone *tz);


This file implements several macros to manipulate and compare timval


Most applications won't care about the API changes. Users have to make
sure, to sync the system clock with the RTC manually if needed.

For any application that need to rely on the old API a new configurator
option has been introduced: "NUT_USE_OLD_TIME_API"

Enable this option, if you would like to stay with the old API. This
might be usefull if you design a low-power system, where the CPU is
sleeping most of the time and shall not be woken up regularly, or if you
use an odd crystal frequency which can not provide a system tick timer
running at an even multiple of 1µs.

I hope that these changes won't break any critical applications! If it
does, please first consider to activate "NUT_USE_OLD_TIME_API" or to
adapt your application to the new API.

Feel free to comment :-)

Best regards,

Ole Reinhardt

kernel concepts GmbH            Tel: +49-271-771091-14
Sieghuetter Hauptweg 48         Mob: +49-177-7420433
D-57072 Siegen

More information about the En-Nut-Discussion mailing list