[En-Nut-Discussion] Re: [btnode-development] Re: Nut errors!?

Matthias Ringwald mringwal at inf.ethz.ch
Wed Jul 6 19:06:50 CEST 2005


Hi Lukas and others,

  I was debugging the second test case and not answering emails. sorry.


For the crash_timers, this is what is happening:

Both worker threads use timers additionally.

On event post, which is optimized for IRQ usage, the callback of the  
timer is cleared
but the timer stays in the queue.

On every thread switch, NutTimersProcesssElapsed is processed to  
really free the timers
which have been elapsed which are all timers from the beginning with  
tn_ticks == 0.
The function does not remove timers, that are after the first running  
timer but have
been disabled because of an event beeing signaled and stay in the  
queue until all
other timers are elapsed. In our case, approx. 330 timers are created  
and disabled
before all timers are freed once.

How to fix:

a first fix is to remove all timers with callback == 0 in  
NutTimersProcesssElapsed (i've attached code for this below)

another would be to move a timer which is stopped in front of the  
timerList. unfortunately, without a double linked list
this is not possible in O(1) in NutTimerStopAsync (which might be  
called from Interrupt context).

So what to do: check all items in the timerlist on every thread  
switch, or used double-linked lists for timers?
(actually, I don't know if there is more to do here.. Harald?)

Matthias

Fix: changed NutTimerProcessElapsed

void NutTimerProcessElapsed(void)
{
     NUTTIMERINFO *tn, *temptn;

     NutDisableTimerIrq();
     runningTimer = 0;
     NutEnableTimerIrq();

     while (nutTimerList && nutTimerList->tn_ticks_left == 0) {
         tn = nutTimerList;
         nutTimerList = nutTimerList->tn_next;
         if (tn->tn_callback) {
             (*tn->tn_callback) (tn, (void *) tn->tn_arg);
         }
         if ((tn->tn_ticks_left = tn->tn_ticks) != 0) {
             NutTimerInsert(tn);
         } else {
             free(tn);
         }
     }

     // remove useless timers
     if (nutTimerList){
         tn     = nutTimerList;
         while (tn->tn_next){

             if (tn->tn_next->tn_callback == 0) {
                 // remove entry from linked list
                 temptn = tn->tn_next;
                 tn->tn_next = tn->tn_next->tn_next;
                 free(temptn);
             }

             tn = tn->tn_next;
         }
     }

     NutDisableTimerIrq();
     runningTimer = nutTimerList;
     NutEnableTimerIrq();
}


On 06.07.2005, at 18:28, Lukas Winterhalter wrote:

> Hi,
> I posted about these problems in the BTnut list already. Now I've
> removed all BTnut specific code from the two attached test apps. They
> are plain Nut/OS now and produce still the same errors. (Running on
> Atmega128L CPU (BTnode3))
>
> crash_timers: ########################
>
> - two worker threads that synhronize each other with
> NutEventPost/NutEventWait
>
> - a sleeper thread that sleeps all the time
> - terminal thread
>
> PROBLEM:
> NutDumpTimerList() prints out garbage.
>
> REPRODUCE:
> 1. just start the crash_timers app
>



More information about the En-Nut-Discussion mailing list