Contiki delay in seconds

3.7k Views Asked by At

I am trying to develop a contiki piece of code in which I need to wait for three seconds for a transducer output. Although this may sound quite un-transducer like, at development time, I want to simulate the behavior at human readable speeds and hence I need to set the timer to say 3 seconds.

The contiki timer library is pretty well documented and has a good series of examples which mention the creation, setting and resetting of the timer. However, if I have code like the following:

timer_set(&transducerOutputWaitTimer);
bool if_blk_executed;
if(timer_expired(&&transducerOutputWaitTimer)){
    if_blk_executed = true;
    //do something
}
if(if_blk_executed)
   printf("Sunrise");
else
   printf("It is not dawned yet");

Now the expiry is not immediately triggered after the timer is set. So the if block is never executed. Effectively it will never dawn.

Now there are two ways in which I can get the system to wait. One, by adding a while loop on the timer like this: while(!timer_expired(&&transducerOutputWaitTimer)){}; //do something

or cpu_delay_usecs{mytimerdur_in_secs*10^6*}; //do something

I do not see that either approaches are elegant. While one wastes CPU cycles, the other enforces an unnecessarily large computation.

Is there any better way? I know that clock

Attached to this question are the following two:

  1. How can I trigger one Contiki protothread from another? If I can do this, I can get the interrupt that causes the transducerOutput to invoke a process from which I can trigger the etimer and process events.

  2. What exactly does the CPU delay mean? Does this mean that the entire CPU clock cycles get held back for the given duration? If yes, how are other processes running currently in the system affected?

Updates Update 1: the while method did not work. The code possibly went into an infinite loop. Update 2: I tried with a clock_delay(3*CLOCK_SECOND) approach after setting my timer. It worked. However, in this case, why do I need the timer method at all?

Update 3 (This changes the context of the answer, hence adding this comment as per the suggestion)

My Timer needs to be used outside a process in a different void function. In that case, I need to use the timer() library rather than the etimer (which is specific to a process. So how do I get my method to wait for the desired time in such cases?

1

There are 1 best solutions below

3
On

There are several Contiki abstractions built on top of the timer library - there is usually no need to user the timer_t structures directly. Instead, there are event timers (struct etimer), which play well together with Contiki processes, and callback timers (struct ctimer), both of which internally use struct timer. For a less RAM hungry option with a more limited API there are second timers (struct stimer). Finally, there is a single real-time timer in the system (struct rtimer).

An example event timer usage: set and wait for 3 seconds:

static struct etimer timer;
etimer_set(&timer, 3 * CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));

How can I trigger one Contiki protothread from another?

There is process_poll - see the process API documentation for more examples.

What exactly does the CPU delay mean?

It's a form of busy waiting. Don't use the delay functions or other forms of busy waiting for delays longer than microseconds - not energy efficient, does not allow other processes to run, and in worst case the watchdog might expire.