An issue with ARM interrupts revisits.

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Nov 22 06:33:04 UTC 2017


On 22/11/17 05:41, groups at chichak.ca wrote:
> Here is the situation, I have my ADCs set up to deliver results using 
> DMA 200 times per second using two interrupt routines. One routine is 
> called when the ADC buffer is half full, the other when the ADC buffer 
> is full. The interrupt routines execute a rtems_event_send call that 
> is picked up in the task code using rtems_event_receive.
>
> If I don’t call rtems_event_receive (wth a timeout of 100 ticks) the 
> code runs for hours. With the rtems_event_send call, it fails after 
> 125 seconds.
>
> The failure is not something that I have seen before:
>
>
> #0  _Terminate (the_source=the_source at entry=INTERNAL_ERROR_CORE, 
> the_error=the_error at entry=31) at 
> /Users/andreichichak/development/rtems/kernel/rtems/c/src/../../cpukit/score/src/interr.c:37
> #1  0x0800bf6e in _Internal_error 
> (core_error=core_error at entry=INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT) 
> at 
> /Users/andreichichak/development/rtems/kernel/rtems/c/src/../../cpukit/score/src/interr.c:52
> #2  0x0800dd38 in _Thread_Do_dispatch (cpu_self=<optimized out>, 
> level=<optimized out>) at 
> /Users/andreichichak/development/rtems/kernel/rtems/c/src/../../cpukit/score/src/threaddispatch.c:186
> #3  0x0800f924 in _ARMV7M_Thread_dispatch () at 
> /Users/andreichichak/development/rtems/kernel/rtems/c/src/../../cpukit/score/cpu/arm/armv7m-isr-dispatch.c:32
>
>
> In _Thread_Do_dispatch, it looks like an maybe an ISR is firing when 
> it is disabled (?) and then _Internal_error is being called.
>
> *void* *_Thread_Do_dispatch*( Per_CPU_Control *cpu_self, ISR_Level level )
> {
> Thread_Control *executing;
>
>   _Assert( cpu_self->thread_dispatch_disable_level == 1 );
>
> *#if* defined(RTEMS_SCORE_ROBUST_THREAD_DISPATCH)
> *if* (
>     !_ISR_Is_enabled( level )
> *#if* defined(RTEMS_SMP)
>       && rtems_configuration_is_smp_enabled()
> *#endif*
>   ) {
>     _Internal_error( INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT );
>   }
> *#endif*
> *
> *
> *
> *
> *Does anybody have any idea where I should look to figure this out?*

We fixed one serious issue in the ARMv7-M interrupt support this year:

http://devel.rtems.org/ticket/3060

This was quite hard to debug. We used a μTrace from Lauterbach 
(http://www.lauterbach.com/flyer_microtrace_web.pdf).

I have absolutely no idea how you can end up in 
_ARMV7M_Thread_dispatch() with an unexpected interrupt level. This 
function is called as a result of an interrupt return:

void _ARMV7M_Pendable_service_call( void )
{
   Per_CPU_Control *cpu_self = _Per_CPU_Get();

   /*
    * We must check here if a thread dispatch is allowed.  Right after a
    * "msr basepri_max, %[basepri]" instruction an interrupt service may 
still
    * take place.  However, pendable service calls that are activated during
    * this interrupt service may be delayed until interrupts are enable 
again.
    */
   if (
     ( cpu_self->isr_nest_level | 
cpu_self->thread_dispatch_disable_level ) == 0
   ) {
     ARMV7M_Exception_frame *ef;

     cpu_self->isr_nest_level = 1;

     _ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVCLR;
     _ARMV7M_Trigger_lazy_floating_point_context_save();

     ef = (ARMV7M_Exception_frame *) _ARMV7M_Get_PSP();
     --ef;
     _ARMV7M_Set_PSP( (uint32_t) ef );

     /*
      * According to "ARMv7-M Architecture Reference Manual" section B1.5.6
      * "Exception entry behavior" the return address is half-word aligned.
      */
     ef->register_pc = (void *)
       ((uintptr_t) _ARMV7M_Thread_dispatch & ~((uintptr_t) 1));

     ef->register_xpsr = 0x01000000U;
   }
}

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
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