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