changes to the core Nios2 RTEMS IIC model

Hill, Jeff johill at lanl.gov
Wed Aug 15 14:41:38 UTC 2012


Hello Sebastian,

> 
> some more comments regarding the thread stack usage of ISRs.
> 
> On 14/08/12 03:05, Hill, Jeff wrote:
> > __attribute__ ((section (".text_hotspot")))
> > void __ISR_Handler ( void )
> > {
> >
> [...]
> 
> The code that calls __ISR_Handler() will save the volatile context on
> the thread stack, right?

correct

> 
> >    if ( _ISR_Nest_level == 0) {
> > #   if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
> >        stack_ptr = _old_stack_ptr;
> > #   endif
> >
> >      if ( !_Thread_Dispatch_in_critical_section() ) {
> >        if ( _Thread_Is_dispatch_necessary () ) {
> >          _CPU_ISR_Enable ( isrCookie );
> 
> What does the _CPU_ISR_Enable() here?  Will it really enable the
> interrupts?  

The _CPU_ISR_Enable will of course _globally_ enable interrupts in the Nios2 
status register.

> In case it enables interrupts then the code that calls
> __ISR_Handler() will save a volatile context on the thread stack (it is
> now the second).  In case the interrupt is pending a long time (some
> sort of error) or you have a bad sequence of interrupts, then this can
> stack several times and blow your thread stack.
> 

With the IIC the interrupt's priority is defined by its bit position 
in the ipending  and ienable register.

Note that this is the Nios2 with internal interrupt controller so a 
particular interrupt will not occur unless it is _also_ enabled in the 
Nios2 ienable register, and as I mentioned in my previous
mail the interrupts of equal or lower priority are previously disabled 
by the following code that writes to the Nios2 ienable register. We will 
not start a new interrupt context for the same or lower priority interrupt
with the IIC unless it is _also_ enabled in the ienable register; therefore
the interrupt contexts will nest only 32 deep.

  uint32_t vector = CPU_INTERRUPT_NUMBER_OF_VECTORS;
  {
    /*
     * we should always take the first branch but conservative
     * code is a good idea for an ISR
     *
     * __builtin_ctz produces undefined result if ipending is
     * zero
     */
    uint32_t newEnbl = NIOS2_IENABLE_NO_INTERNAL_INTERRUPTS;
    if ( ipending ) {
      vector = __builtin_ctz ( ipending );
      if ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS ) {
        pHandler = _ISR_Vector_table[ vector ];
        /*
         * disable nios2 internal interrupts of equal or lower level
         * (we restore the interrupt level in the low level code
         * so that we dont explode the interrupt stack when there
         * is an unquenched interrupt source)
         *
         * Bit 0 in the ipending register has highest priority
         * and bit 31 has lowest priority.
         */
        newEnbl = ( 1u << vector ) - 1u;
      }
    }
    __builtin_wrctl ( NIOS2_CTLREG_INDEX_IENABLE, newEnbl );
  }

> >          _Thread_Dispatch ();
> >          /* may have switched to another task and not return here immed.
> */
> >          _CPU_ISR_Disable ( isrCookie ); /* Keep _pairs_  of
> Enable/Disable */
> >        }
> >      }
> >    }
> >
> >    _CPU_ISR_Enable( isrCookie );
> > }
> 

Best regards,

Jeff

> 
> --
> Sebastian Huber, embedded brains GmbH
> 
> Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
> Phone   : +49 89 18 90 80 79-6
> Fax     : +49 89 18 90 80 79-9
> E-Mail  : sebastian.huber at embedded-brains.de
> PGP     : Public key available on request.
> 
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.





More information about the users mailing list