[En-Nut-Discussion] interrupt context and API safety

Tim Tait tim.tait1 at gmail.com
Fri Jan 27 19:04:45 CET 2006


I came across this today as I was learning about NutOS. From 
<http://www.ethernut.de/en/documents/ntn-2_events.html>:

-------------
In our given example, only the idle thread is left. When the idle thread 
is doing nothing except calling |NutThreadYield| in a loop, who is 
posting an event while both worker threads are sleeping? Well, there are 
two special calls, which can be called from within interrupt routines.

  int NutEventPostAsync(HANDLE volatile *qhp);
  int NutEventBroadcastAsync(HANDLE * qhp);

The main difference to |NutEventPost| and |NutEventPostAsync| is, that 
Nut/OS will move the |NUTTHREADINFO| structures and update the 
|td_state| values, but will not switch the CPU control. This is actually 
done when the idle thread calls |NutThreadYield|. Nut/OS provides 
cooperative multithreading, which means, that a thread can rely on not 
losing CPU control without calling specific system function which may 
change its state. However, interrupts are preemptive in any case. By 
delaying the context switch, Nut/OS ensures, that cooperative 
multithreading is maintained even when interrupts are able to wake up 
sleeping threads.
------------

Tim

William Baker wrote:

> I am attempting to use an async timer to awaken an OS level thread.  
> The async timer handler posts an event to the event queue using 
> NutEventPost()...and that is probably a no-no.  All I know about API 
> calls from an async timer handler is what the documentation states:
>
> > The callback function is executed in interrupt context at a very 
> high priority. It
> > can call only a limited set of functions and must return as soon as 
> possible.
>
> Which makes sense, although exactly what is meant by "limited set of 
> functions" is not well defined.  So I tried it, and my app works -- 
> for a while.  As the app runs, one eventually sees the kind of memory 
> corruption you would expect from async threads stepping on each other 
> or random pointers.
>
> The app has two time critical threads that need to kick off every 10ms 
> to send data out the serial ports.  It also has threads that maintain 
> active communication with an ethernet device, and provides 
> setup/diagnostics/configuration via http threads.
>
> Would it be sufficient to put a "disable-interrupt/enable-interrupt" 
> around some OS functions to make them safe?  It seems like the 
> disable/enable interrupt macros in AVRGCC have changed recently.
>
> Ideas are welcome to either make the async timer work reliably or an 
> alternate approach.
>
> bbaker
>




More information about the En-Nut-Discussion mailing list