Timers

From Contiki
Revision as of 22:53, 4 March 2014 by Timothy (Talk | contribs)

Jump to: navigation, search

Back to Contiki Tutorials

Introduction

Timers can be used to control periodic tasks as well as implement sophisticated algorithms. The implementation of each type of timer is platform-dependent and has different properties that make them useful in specific situations; some timers have low granularity (seconds) and overflow once in tens of years, and others provide high granularity (microseconds), but overflow rapidly. There are 5 types of timers provided by Contiki:

  • timer
  • stimer
  • ctimer
  • etimer
  • rtimer

Overview

The functions of all types of timers are located inside folder core/sys/{timer, stimer, ctimer, etimer, rtimer}.{c,h}. A complete documentation of Timers in Contiki can be found here.

The timer and stimer are the most basic types of timers and are used to check if a time interval has passed. They do not notice when the time period has elapsed, so the application needs to check periodically if they have expired. The difference between them is the resolution: timers use system clock ticks, which gives high granularity (order of microseconds) but short overflow periods (order of seconds). On the other hand, stimers use seconds to allow much longer time periods (order of years), but has lesser granularity.

The etimer provides event timers and are used to schedule events to the processes after a period of time. They are used in Contiki processes to wait for a time period while the rest of the system can work or enter low power mode.

The ctimer provides callback timers and are used to schedule calls to functions after a period of time. Like event timers, they are used to wait for some time while the rest of the system can work or enter low power mode. Since the callback timers call a function when a timer expires, they are especially useful in any code that do not have an explicit Contiki process such as protocol implementations.

The rtimer provides scheduling of real-time tasks. The rtimer library preempts any running Contiki process in order to let the real-time tasks execute at the scheduled time. The real-time tasks are used in time critical codes.

You will learn

  • Simple implementations of each type of timer
  • Tasks each timer can be used for
  • Some functions in the timer libraries.

Step 1

Again, we will have to change folders. We will create a new file for this tutorial, but let's create it in the same directory we've been working with, so type

cd contiki-2.7/examples/rime

into the terminal. For this tutorial, we will be modifying the example-broadcast.c file we have previously used, so type

cp example-broadcast.c example-timer.c

into your terminal. You should now see a new file, "example-timer.c" in your directory. Open it up with an editor of your choice (we will use gedit for this tutorial):

edit example-timer.c

Step 2

There is currently a working example of an etimer in this code, so before we proceed, let's understand this. At the beginning of the process, it is declared with

static struct etimer et;

This creates an etimer instance. Within the while loop, it is set with the function

etimer_set(&et, CLOCK_SECOND*4 + random_rand() % (CLOCK_SECOND * 4));

This function takes the arguments:

etimer_set(struct etimer *et, clock_time_t interval);

and sets the etimer et to expire after interval.

After that, we see the line:

PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

which tells the example_broadcast_process to pause until it receives an event, so the program is essentially giving up system control. When an etimer expires, it posts a PROCESS_EVENT_TIMER event to the example_broadcast_process. So this tells the process to continue and begin running again, as the etimer has expired, and an event has been posted. Now that we understand what the etimer is doing here, let's incorporate some other timers.

Step 3

To start simply, we are going to use a timer to just print out a message once it expires. Just below

static struct etimer et;

declare a timer with the line:

static struct timer t;

Before the while loop, set the timer with the line:

timer_set(&t, CLOCK_SECOND * 10);

This sets the timer to expire after 10 seconds.

Below the line

printf("broadcast message sent\n");

add in the code:

if(timer_expired(&t)){ printf("Timer expired\n"); }

Now, save and run your code on your Tmote Sky by typing into your terminal:

make TARGET=sky example-timer.upload

If you don't have a Sky, run this code on Mspsim with the line

make TARGET=sky example-timer.mspsim

Among the "broadcast message sent" messages, you should see a "Timer expired" notice. This only occurs one time, however. This is because we never reset the timer. So, return to your example-timer.c file. Underneath your printf("Timer expired\n") line, add the code

timer_reset(&t);

This will reset the timer to expire again in 10 * CLOCK_SECONDS. Run your code again. You should now see "Timer expired" every few broadcast messages. Now, say we only wanted to send broadcast messages for 30 seconds. Let's use our timer to exit our process after it expires. Change your original timer_set function to:

timer_set(&t, CLOCK_SECOND * 30);

Now, just delete the line

timer_reset(&t);

and replace it with

PROCESS_EXIT()

Run your code again, and it should stop after the timer expires. You have now learned some basic functionality of the timer.

Step 4

Back to Contiki Tutorials