Objective
The objective of this tutorial is to understand which is the lowest resolution that etimer(ms) and rtimer(us) can provide. In order to do this tutorial i used sky motes, however, the same procedure applies to other architectures. I tested the code in Contiki v3.0 and lubuntu 16.04.
Some Background
The lowest resolution of the etimer is given by the CLOCK_SECOND constant, and for the rtimer is given by the RTIMER_ARCH_SECOND constant. The formula for obtaining the lowest etimer resolution is 1 / CLOCK_SECOND seconds, and for obtaining the lowest rtimer resolution is 1 / RTIMER_ARCH_SECOND seconds. Or in Adam Dunkels' words "The only constant is the RTIMER_ARCH_SECOND. I.e., if you have a hardware timer that runs at 32768Hz, the rtimer units is 1/32768 s and RTIMER_ARCH_SECOND is 32768" (See Reference [1] below).
Check the CLOCK_SECOND and the RTIMER_ARCH_SECOND value
So, in order to know the lowest etimer and rtimer resolution you need to know the value of the CLOCK_SECOND and RTIMER_ARCH_SECOND constants, respectively. Following this, to print that values in console you must run the following code in one node. The code creates the #define SHOW_DEFINE(x), which is used to print the values of the constants CLOCK_SECOND and RTIMER_ARCH_SECOND
/* * Copyright (c) 2007, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file is part of the Contiki operating system. * */ /** * \file * Show CLOCK_SECOND and RTIMER_ARCH_SECOND values * \author * Sergio Diaz */ /*INCLUDES*/ #include "contiki.h" //Show #define values: To USE them put it in the process like this: // SHOW_DEFINE(CLOCK_SECOND); // SHOW_DEFINE(RTIMER_ARCH_SECOND); #define STR(x) #x #define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x)) /*---------------------------------------------------------------------------*/ PROCESS(show_define_values, "Show define values"); // Declares the process to show the #define values AUTOSTART_PROCESSES( &show_define_values); // Load the process on boot PROCESS_THREAD(show_define_values, ev, data) // Start of the process to show the #define values { static struct etimer et; PROCESS_BEGIN(); // Says where the process starts while(1) { //Printf value every 1 second etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); //Wait for etimer (et) to expire SHOW_DEFINE(CLOCK_SECOND); // Show the value of the CLOCK_SECOND in console. To be aware of the etimer resolution SHOW_DEFINE(RTIMER_ARCH_SECOND); // Show the value of the RTIMER_ARCH_SECOND in console. To be aware of the rtimer resolution printf("\n"); //Printf a "\n" } PROCESS_END(); //Says where the process ends } /*---------------------------------------------------------------------------*/
When you run this code in a Sky mote and view the messages in the console, then you will see this:
CLOCK_SECOND=128UL RTIMER_ARCH_SECOND=(4096U*8)
That means that the CLOCK_SECOND value is 128 Unsigned (U) Long (L), and that the RTIMER_ARCH_SECOND value is 4096 Unsigned (U) * 8, it means RTIMER_ARCH_SECOND value is 32768. So the lowest resolution for etimer is 1 / CLOCK_SECOND = 1 / 128 s = 7,8125 ms. Besides, the lowest resolution for rtimer is 1 / RTIMER_ARCH_SECOND = 1 / 4096U*8 = 1 / 32768 = 30,5175 us.
Example Setting etimer and rtimer
If you want to set the etimer and rtimer to the lowest resolution in the sky mote you can do the following.
etimer_set(&et, (CLOCK_SECOND / 128) ); //The etimer expires in 7,8125 ms rtimer_set(&rtimer, RTIMER_NOW() + (RTIMER_ARCH_SECOND / 32768) , 1, carrier_OnOff, NULL);// The rtimer expires in 30,5175 us
You can not use a bigger number than 128 to divide the CLOCK_SECOND, and you can not use a bigger number than 32768 to divide the RTIMER_ARCH_SECOND; because you can not have a bigger resolution without changing the default behaviour of the sky node. If you want the timers to expire in 0,5 seconds you can do this:
etimer_set(&et, (CLOCK_SECOND / 2) ); //The etimer expires in 0,5 s rtimer_set(&rtimer, RTIMER_NOW() + (RTIMER_ARCH_SECOND / 2) , 1, carrier_OnOff, NULL);// The rtimer expires in 0,5 s
References
[1] https://sourceforge.net/p/contiki/mailman/message/18577635/
Thank you Sergio, Good explanation
ReplyDelete