how to suspend current running thread from within exception level handler

Hill, Jeffrey O johill at lanl.gov
Tue May 1 23:15:17 UTC 2012


> First you are violating the RTEMS API badly and going into
> the SuperCore which is not allowed.

So, this is a default exception handler and a per-exception-type 
handler jump table that actually is currently implemented 
inside of my modifications to the nios2 specific part of super 
core. I attached the code in case you would like to have a 
look. 

I do suppose that the code, filtering for an interrupt in progress 
and also multithreading not started, maybe could occur before calling 
the user's exception handler although perhaps this will restrict 
some specialized situations such as emulating unimplemented 
instructions in software (even if an ISR or startup is in progress).
Admittedly making every combination work reliably might require some
effort.

Certainly the user's exception handler should be called with 
interrupts enabled, and in fact I just checked and I was doing 
that all along. 

I did consider the idea of using pthread_kill to deliver the 
POSIX signal mapping of the nios2 exception to the current 
running thread, but I didn't see any evidence of this, or any 
other standardized approach, being implemented in any of the 
BSPs, or in any part of super core when I looked into this some 
time back. I'm definitely an RTEMS newbie however, so I could 
easily be missing how this all goes together. Any suggestions 
are greatly appreciated.

> If not registered as an RTEMS interrupt handler, then
> you can't make RTEMS calls during this at all. That
> limits your options considerably to change a task state.

The __Exception_Handler function in the attached code is 
being called directly by this code.

cpukit/score/cpu/nios2/nios2-iic-low-level.S

So needless-to-say it isn't a "registered" RTEMS interrupt 
handler that increments the ISR nest level etc. 

Maybe what is needed is to implement a minimal 
__Exception_Handler in super core properly managing 
the environment (i.e. properly calling 
_Thread_Dispatch_increment_disable_level etc), but 
the rest of the exception jump table should be moved 
into the shared part of the BSP. Any suggestions, or 
pointers to example codes in super core setting up a
proper environment for a user's exception handler, are 
greatly appreciated.

Jeff

> 
> I think you need to carefully consider each state the system
> and CPU can be in when you get to this point.
> 
> + exception during RTEMS initialization
> + exception during a task
> + exception during an ISR
> 
> And you have to consider whether this exception handler
> is being registered as an RTEMS interrupt handler or not.
> 
> If not registered as an RTEMS interrupt handler, then
> you can't make RTEMS calls during this at all. That
> limits your options considerably to change a task state.
> 
> If registered as an RTEMS interrupt handler, then
> rtems_interrupt_is_in_process() will always return true.
> That's an issue.
> 
> rtems_task_suspend() is safe from an ISR  and should be
> used instead of the score routines you are calling.
> 
> When in an RTEMS interrupt handler, you are always
> in a thread dispatching disabled critical section.  If you
> interrupted an RTEMS dispatching disabled section,
> then the value of (dispatch disable count - isr nest level) > 0.
> 
> When you get to this point, your options are generally
> very limited. You can attempt to suspend the task and
> continue. But if inside RTEMS, the system is dead at this
> point.
> 
> If you didn't get an exception while in a thread and outside
> RTEMS, I am betting you can't do anything except halt or
> reset.
> 
> Most of this can be done via the public API and those that can't
> are open points for discussion for additions.
> 
> It is also worth considering that the states above I defined
> are true across all ports and BSPs. Thus a framework
> for an exception handler may make a lot of sense here.
> There are not many options and it would be relatively
> easy to make those available to the BSP author. The
> decision of:
> 
> + during initialization
> + inside RTEMS at task level
> + outside RTEMS at task level
> + during ISR
> 
> Is portable.
> 
> --joel
> 
> 
> On 05/01/2012 02:08 PM, Hill, Jeffrey O wrote:
> > Hi,
> >
> > I am writing a last chance RTEMS exception handler function for the
> nios2 processor. In this function I attempt to suspend the current running
> thread, and switch to the next runable thread. Here is the (probably
> naïve) code I tried to write to accomplish that aim, but I don't know if
> it's even close to correct. Any comments from the gurus?
> >
> >          if ( !_States_Is_suspended ( _Thread_Executing->current_state )
> ) {
> >              _Thread_Suspend ( _Thread_Executing );
> >              /*
> >               * we cant call _Thread_Dispatch here because interrupts
> >               * are currently disabled
> >               */
> > #if 0
> >              if ( !_Thread_Dispatch_in_critical_section() ) {
> >                  _CPU_ISR_Enable( isrCookie );
> >                  _Thread_Dispatch();
> >                  _CPU_ISR_Disable( isrCookie );
> >              }
> > #endif
> >          }
> >
> > Attached is also the current state of the (somewhat) complete last
> chance exception handler for context. When I attach with the debugger
> after the fault has already occurred I don't appear to see the faulting
> thread in the thread list whereas I can at least sometimes see the
> faulting thread if the debugger is already attached when the exception
> happens (in that situation my last chance exception handler doesn't run).
> >
> > Thanks for your help,
> >
> > Jeff
> >
> > static void __Exception_Handler_Last_Resort ( uint32_t cause,
> CPU_Exception_frame * pefr )
> > {
> >      printk ( "\n" );
> >      printk ( "\07" ); /* ding */
> >      printk (
> >          "**** Unexpected nios2 \"%s\" exception\07\n",
> >          _Nios2_Exception_Cause_Name ( cause ) );
> >      static const char * const pCloseMsg =
> >
> "*****************************************************************\n";
> >      if ( _ISR_Is_in_progress () ) {
> >          printk (
> >          "**** Executing in an interrupt service routine, halting
> processor\n" );
> >          printk ( pCloseMsg );
> >          _CPU_Fatal_halt(0xECC0);
> >      }
> >      else if ( _Thread_Executing ) {
> >          char threadName[32]; /* maybe only needs to be 4 characters */
> >          const char * pName;
> >          {
> >              uint32_t isrCookie;
> >              _CPU_ISR_Disable( isrCookie );
> >              pName = _Objects_Get_name_as_string (
> >                                  _Thread_Executing->Object.id,
> >                                  sizeof ( threadName ), threadName );
> >              _CPU_ISR_Enable( isrCookie );
> >          }
> >          if ( ! pName ) {
> >              pName = "anonymous";
> >          }
> >          printk ( "**** Suspending thread \"%s\"\n", pName );
> >          printk ( pCloseMsg );
> >          /*
> >           * I am operating under the assumption that interrupts are
> locked
> >           * out while the exception handler is running so this code
> would
> >           * need to change if that situation changes.
> >           */
> >          if ( !_States_Is_suspended ( _Thread_Executing->current_state )
> ) {
> >              _Thread_Suspend ( _Thread_Executing );
> >              /*
> >               * we cant call _Thread_Dispatch here because interrupts
> >               * are currently disabled
> >               */
> > #if 0
> >              if ( !_Thread_Dispatch_in_critical_section() ) {
> >                  _CPU_ISR_Enable( isrCookie );
> >                  _Thread_Dispatch();
> >                  _CPU_ISR_Disable( isrCookie );
> >              }
> > #endif
> >          }
> >      }
> >      else {
> >          printk ( "**** Multitasking hasn't started, halting
> processor\n" );
> >          printk ( pCloseMsg );
> >          _CPU_Fatal_halt(0xECC0);
> >      }
> > }
> >
> > _______________________________________________
> > rtems-users mailing list
> > rtems-users at rtems.org
> > http://www.rtems.org/mailman/listinfo/rtems-users
> 
> 
> --
> Joel Sherrill, Ph.D.             Director of Research&   Development
> joel.sherrill at OARcorp.com        On-Line Applications Research
> Ask me about RTEMS: a free RTOS  Huntsville AL 35805
>      Support Available             (256) 722-9985
> 

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: nios2-except.c
URL: <http://lists.rtems.org/pipermail/users/attachments/20120501/603bdd16/attachment-0001.c>


More information about the users mailing list