[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