We can perform some activities by utilizing timer objects. Contiki-NG has one clock and several timer modules, such as timer
, stimer
, ctimer
, etimer
, and rtimer
. All these libraries can be found in the <contiki>/os/sys
folder.
Contiki-NG provides a set of timer libraries that are used both by applications and by the OS itself. The timer libraries contain functionality for checking if a time period has passed, waking up the system from low power mode at scheduled times, and real-time tasks scheduling.
All the timers build on the clock
module, in charge of basic system time:
timer
: a simple timer, without built-in notification (caller must check if expired). Safe from interrupt.stimer
: same as timer, but in seconds and with significantly longer wrapping period. Safe from interrupt.etimer
: schedules events to Contiki-NG processes. Unsafe from interrupt.ctimer
: schedules calls to a callback function. Unsafe from interrupt.rtimer
: real-time task scheduling, with execution from ISR. Safe from interrupt.
Clock Module
The Clock library can be used for doing general activities with time. It is declared in clock.h
from the <contiki>/os/sys
folder. We can see the content of the clock.h
file here:
1 | clock_time_t clock_time(); // Get the system time. |
To use this library, call these functions directly from the program. For instance, we can access a clock time by calling the clock_time()
function:
1 | clock_time_t t = clock_time(); |
The system time is specified as the platform dependent type clock_time_t
and in most platforms this is a limited unsigned value which wraps around when getting to large. The system time starts from zero at boot. In addition, clock_wait()
blocks the CPU for a specified number of clock ticks.
Timer Library
The Timer
library provides functions for setting, resetting, and restarting timers, and for checking if a timer has expired. A timer is declared as a struct timer
and all access to the timer is made by a pointer to the declared timer. This library is found in the timer.h
file and defines several functions as follows:
1 | void timer_set(struct timer *t, clock_time_t interval); // Start the timer. |
An application must manually check if its timers have expired. To use the Timer library, we call timer_set()
. Then, we can verify an expired timer by calling the timer_expired()
function:
1 | timer_set(&timer_timer, 3 * CLOCK_SECOND); |
A timer is always initialized by a call to timer_set()
which sets the timer to expire the specified delay from current time and also stores the time interval. All the other function operate on this delay. The following example shows how a timer can be used to detect timeouts in an interrupt.
1 |
|
Stimer Library
The Contiki-NG stimer
library provides a timer mechanism similar to the timer library but uses time values in seconds, allowing much longer expiration times. The stimer
library use clock_seconds()
in the clock module to get the current system time in seconds.
The Stimer
library is similar to the timer library, but uses time values in seconds. The following is a list of Stimer
functions defined in the stimer.h
file.
1 | void stimer_set(struct stimer *t, unsigned long interval); // Start the timer. |
We can use the Stimer
library with the same approach as the timer library. We set a time by calling stimer_set()
. Then, we check for an expired timer using the stimer_expired()
function:
1 | stimer_set(&stimer_timer, 3); |
Notice: the stimer
cannot add the CLOCK_SECOND
!
Etimer Library
The Etimer
library is an event timer library that generates an event. We can verify this event using PROCESS_WAIT_EVENT_UNTIL()
. We can see event timer declarations in the etimer.h
file:
1 | void etimer_set(struct etimer *t, clock_time_t interval); // Start the timer. |
For demo purposes, we can call etimer_set()
to set our event timer. Then, we wait for the expired event using PROCESS_WAIT_EVENT_UNTIL()
:
1 | etimer_set(&etimer_timer, 3 * CLOCK_SECOND); |
An event timer will post the event PROCESS_EVENT_TIMER
to the process that set the timer when the event timer expires. The etimer
library use clock_time in the clock module to get the current system time. The etimer
library use clock_time in the clock module to get the current system time. An event timer is declared as a struct etimer
and all access to the event timer is made by a pointer to the declared event timer.
Note that the timer event is sent to the Contiki-NG process used to schedule the event timer. If an event timer should be scheduled from a callback function or another process, PROCESS_CONTEXT_BEGIN()
and PROCESS_CONTEXT_END()
can be used to temporary change the process context. The following example shows how an etimer
can be used to schedule a process to run once per second.
1 |
|
Ctimer Library
The CTimer
library provides a function callback that will be called when timer expiration occurs. CTimer
functions are defined in the ctimer.h
file:
1 | void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr); // Start the timer. |
For this demo, we can define a function, perform_ctime_function()
. This function is passed to ctimer_set()
when we set the ctimer
library:
1 | void perform_ctime_callback() |
Rtimer Library
The Rtimer
library provides scheduling and execution for real-time tasks. We can define a specific execution time when we set rtimer
using the rtimer_set()
function. We can see the rtimer
function in
the rtimer.h
file:
1 | RTIMER_CLOCK_LT(a, b); // This should give TRUE if 'a' is less than 'b', otherwise false. |
For implementation, we declare a function that is passed in the rtimer_set()
function. We also set the execution time:
1 | static rtimer_clock_t timeout_rtimer = RTIMER_SECOND / 2; |