RTEMS scheduler bug ?
Catalin Demergian
demergian at gmail.com
Thu Apr 4 12:09:45 UTC 2019
Hi Andrei,
thank you for the elaborated answer !
I checked my STM32 Cube settings, I have 3 enabled interrupts and they all
have the preemption priority/sub priority set to zero !
it seems I ran into the same issue you had in 2015 :)
I will take your advice - change the priorities, regenerate the code and
see what happens.
regards,
Catalin
On Wed, Apr 3, 2019 at 6:03 PM <groups at chichak.ca> wrote:
> This sounds like a problem I had in 2015 on an STM32 that Sebastian helped
> me get around. At the end of the ordeal I wrote:
>
> "A bit of review to begin with; I am working with an STM32F4 ARM Cortex
> M4F processor’s ADC section. A feature of this ADC is the ability to have
> conversions triggered by a timer (great for evenly sampled signals), the
> results transferred using double buffered DMA, giving you an interrupt when
> the DMA buffer is half full, then again when the buffer is full.
>
> To let my task know when there was data ready to process, the DMA
> half/full complete interrupt routines would call rtems_event_send. The task
> would pend on the events, with a timeout in case something screwed up.
>
> In my case, the timer would trigger 14 channels of ADC conversions to
> happen 400 times per second. This would yield 200 half full and 200 full
> interrupts per second, each calling rtems_event_send.
>
> This action would proceed for a few thousand seconds and then the program
> would crash and, doing some painful debugging, I managed to repeatedly
> catch the system attempting to expire some “watchdogs”, which I believe is
> the squelching of outstanding timeouts on satisfied rtems_event_receive
> calls.
>
>
>
> After trying a whole bunch of dead ends, Sebastian Huber asked me about
> the priorities of the interrupts being generated.
>
> The ARM architecture uses a vectored interrupt structure quite similar to
> the MC68xxx processors, where a device generates an interrupt and the
> address of the service routine is automatically picked up from a known
> place in a table without having to poll a bunch of registers to figure out
> what happened and branch off to the handler. The ARM processors have
> assignable priorities on most of the interrupts, so if two interrupts
> assert at the same time, or if a higher priority interrupt happens while an
> interrupt is in progress, you can predict what happens.
>
> What I didn’t know is that RTEMS implements something called Non-Maskable
> Interrupts (NMI). The software NMIs don’t seem to be like hardware NMIs (a
> hardware interrupt that can not be turned off), they just have the same
> name (much like the event watchdogs that aren’t like the hardware
> watchdogs).
>
> What I learned was that RTEMS NMIs are interrupt routines that are not
> allowed to use any RTEMS facilities. So, I presume, these routines would be
> used for dealing with devices that don’t need to interact with task code.
> The upside is that the interrupts can be entered bypassing RTEMS’ overhead.
>
> A drawback is that if you call for RTEMS facilities from within one of
> these routines, apparently, your code becomes rather crashy.
>
>
>
>
> To differentiate between NMI routines and a regular ISR that can call
> RTEMS facilities, the developers use the interrupt priorities and a mask.
> The NMI determination is not specific to the ARM family, each architecture
> has a mask that determines which bits are used to determine if an interrupt
> routine is an NMI or an ISR.
>
>
> ARM uses an 8 bit priority and a priority in the range of 0x00-0x7F
> indicates an NMI. On an ARM, the lower the number, the more urgent the
> interrupt, so NMIs have higher urgency than ISRs that can use RTEMS
> facilities.
>
>
> On the STM32F4, only 4 bits of 8 of priority are implemented, the 4 MSBs
> with the lower 4 being set to 0 (other Cortex M4 implementations have other
> combinations). In ST’s CubeMX tool, you can set the interrupt priority of
> the various interrupt sources in the range of 0-15 and Cube generates code
> to take care of the bit shifting for you. In my case I had set my
> priorities to 1,2,3 and 6. Shifted, these became 0x10, 0x20, 0x30, and
> 0x60. Since these numbers are all below 0x80, the RTEMS code was
> interpreting these interrupts as NMIs, bypassing a bunch of the necessary
> code to support RTEMS calls.
>
> By changing my interrupt priorities to 9, 10, 11, and 14 (shifting gives
> 0x90, 0xA0, 0xB0, and 0xE0), the interrupt routines lost their NMI nature
> and the system immediately became dead stable with a 1kHz tick interrupt
> rate, 2 ADC DMA interrupts at 200Hz each, and a CAN interrupt at about 36Hz.
> ”
>
>
>
> When I ported RTEMS5 to the STM32F7, I ran into the same issue and used
> the same method to get around it.
>
> I hope this helps.
>
> Andrei
>
>
>
>
>
> On 2019-April-03, at 07:46, Sebastian Huber <
> sebastian.huber at embedded-brains.de> wrote:
>
> On 03/04/2019 15:41, Catalin Demergian wrote:
>
> yes, I realized yesterday evening that gIntrErrs could be incremented in
> the second if.
> so I rewrote it like this
>
> int gIntrptErrs;
> int gInsertErrs;
>
> RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
> Chain_Node *node,
> Scheduler_priority_Ready_queue *ready_queue,
> Priority_bit_map_Control *bit_map
> )
> {
> Chain_Control *ready_chain = ready_queue->ready_chain;
> //_Assert(_ISR_Get_level() != 0);
> if(_ISR_Get_level() == 0)
> gIntrptErrs++;
>
> cnt_before = _Chain_Node_count_unprotected(ready_chain);
> _Chain_Append/*_unprotected*/( ready_chain, node );
> cnt_after = _Chain_Node_count_unprotected(ready_chain);
>
> if(cnt_after != cnt_before + 1)
> gInsertErrs++;
>
> _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
> }
>
> It didn't seem that we enter that code with interrupts enabled .. output
> was
> # cpuuse
>
> -------------------------------------------------------------------------------
> CPU USAGE BY THREAD
>
> ------------+----------------------------------------+---------------+---------
> ID | NAME | SECONDS |
> PERCENT
>
> ------------+----------------------------------------+---------------+---------
> *cdemergian build 11.15 gIntrptErrs=0 gInsertErrs=2*
> 0x09010001 | IDLE | 244.595117 | 99.238
> 0x0a010001 | UI1 | 1.000929 | 0.406
> 0x0a010002 | ntwk | 0.099342 | 0.040
> 0x0a010003 | SCtx | 0.068705 | 0.027
> 0x0a010004 | SCrx | 0.089272 | 0.036
> 0x0a010005 | eRPC | 0.000050 | 0.000
> 0x0a010006 | SHLL | 0.550608 | 0.223
> 0x0b010001 | | 0.000096 | 0.000
> 0x0b010002 | | 0.068307 | 0.027
>
> ------------+----------------------------------------+---------------+---------
> TIME SINCE LAST CPU USAGE RESET IN SECONDS: 246.528065
>
> -------------------------------------------------------------------------------
> [/] #
> Not all time time, most of the runs both globals were zero, which is wierd
> ..
>
> I also tried the patch. The issue was reproduced as well.
> [/] # cpuuse
>
> -------------------------------------------------------------------------------
> CPU USAGE BY THREAD
>
> ------------+----------------------------------------+---------------+---------
> ID | NAME | SECONDS |
> PERCENT
>
> ------------+----------------------------------------+---------------+---------
> *cdemergian build 16.25 gIntrptErrs=233694 gInsertErrs=1*
> 0x09010001 | IDLE | 94.488726 |
> 98.619
> 0x0a010001 | UI1 | 1.000931 |
> 1.044
> 0x0a010002 | ntwk | 0.030101 |
> 0.031
> 0x0a010003 | SCtx | 0.021441 |
> 0.022
> 0x0a010004 | SCrx | 0.027176 |
> 0.028
> 0x0a010005 | eRPC | 0.000049 |
> 0.000
> 0x0a010006 | SHLL | 0.215693 |
> 0.225
> 0x0b010001 | | 0.000096 |
> 0.000
> 0x0b010002 | | 0.027211 |
> 0.028
>
> ------------+----------------------------------------+---------------+---------
> TIME SINCE LAST CPU USAGE RESET IN SECONDS: 95.867059
>
> -------------------------------------------------------------------------------
>
> we are getting big numbers for gIntrptErrs (is that normal ? I don't
> understand all the aspects of the patch just yet)
>
>
> Can you set a break point to the gIntrptErrs++ and print the stack traces?
>
> --
> 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
> <sebastian.huber at embedded-brains.de>
> PGP : Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>
> _______________________________________________
> users mailing list
> users at rtems.org
> http://lists.rtems.org/mailman/listinfo/users
>
>
> _______________________________________________
> users mailing list
> users at rtems.org
> http://lists.rtems.org/mailman/listinfo/users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20190404/3ab3ec78/attachment.html>
More information about the users
mailing list