I recently cam across a possible bug in the Timer module for the IRIS
motes. I occasionally noticed that the timer would fire very late thus
causing a whole series of cascading failures in my modules.

After days of debugging, I traced the problem to the routine setInterrupt()
in the  module Atm1281AlarmAsyncP.
If the alarm is armed to fire after 1 TCNT tick, in some situations OCR2A
will be loaded with a value that will essentially be in the "past",  thus
requiring TCNT2 to wrap around for the compare to occur (about 255 ms late).
Since TCNT2 is a free running timer, if TCNT2 increments after the current
time is captured by the call to Counter.get(), the *fired *flag will not be
set, even though the alarm has technically expired. After this, under some
circumstances, the compare register can be loaded with a wrong value.
Consider the following situation when setInterrupt() is called


to = 24
dt = 1
TCNT2 =1
base = 23

now if TCNT increments (TCNT2 = 2)  after the current  time is captured
  uint32_t now = call Counter.get();

Then the following condition will fail
 /* Check if alarm expired */
   if ((uint32_t)(now - t0) >= dt)
The following variables will be updated as indicated below, to compute
 anew value for OCCR2A
alarm_in = 2
newOcr2A = 1

Since newOcr2A   =1  and TCNT2 =2 , When OCCR2A is loaded, it will delay
the next alarm by 255 ms.

As a quick workaround, i added the following code to force the timers to
fire after calling setOcr2A(newOcr2A);

//work around
if(newOcr2A >= TCNT)
{
diff =  newOcr2A - TCNT   ;
}
else
{
diff =  (0xFF - TCNT) + newOcr2A ;
}
if( diff   > MAXT)
{
fired = TRUE;
}
_______________________________________________
Tinyos-help mailing list
Tinyos-help@millennium.berkeley.edu
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help

Reply via email to