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; |