STM32L1xx -- uxPendedTasks value in tasks.c underflow

kagnewkid wrote on Wednesday, January 08, 2014:

Discovered a situation where the value, uxPendedTicks in tasks.c, can underflow and hang the task switching.

In tasks.c, I added a check for underflow at around line 1413 (following the decrement of uxPendedTicks) as follows:

if (0 != (uxPendedTicks & 0x10000000))

I am not entirely sure WHY this situation occurred.

Am running version 7.6.0 and using the STM M3 core port and the IAR development chain.
My project consists of about 6 tasks of equal priority and very low functionality. The interrupt processing that I am doing does not invoke any FreeRTOS facilities so the ISRs are not using the FreeRTOS stack framing macros.
Due to critical timing (bit pacing for one-wire communications) kernel interrupt priority is set lower (less responsive) than the priorities of my one-wire interrupts.

I initially submitted a ticket on this but was encouraged to submit this as a forum topic for discussion to determine whether this should truly be considered a bug or if I have misapplied something that led to this behavior.

Thanks in advance for any advice in this situation.


rtel wrote on Wednesday, January 08, 2014:

That is not an issue that has been reported before, so I will have to take a look through the code as to where the variable is used to see which scenarios could lead to this happening. It sounds like your application is very simple, especially as you are not using FreeRTOS calls from interrupts.

I note you are using an STM32. Is your application code calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before it starts the scheduler? That is essential on STM32 chips only - as unlike any other Cortex-M system I’m aware of, they default to having some priority bits assigned as sub-priority rather than preemption priority. If that is the case then, depending on other configurations, it is possible that the tick interrupt is interrupting a critical section - and that in turn could lead to a context switch in a critical section - which could in turn lead to the uxPendedTicks variable being corrupted in the way you describe (because the variable assumes context switches are not going to happen in critical sections).

Also, as you are using V7.6.0, do you have configASSERT() defined? V7.6.0 includes additional assert statements to check against just the sort of scenario I describe above.


kagnewkid wrote on Wednesday, January 08, 2014:

The NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); call was NOT being made.

The configASSERT() is defined.

I have added the NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); per your requirement and it appears to have solved the problem.

I think in retargeting your sample application, I overlooked and then omitted the call. Not wise.
Thanks for your assistance.

kagnewkid wrote on Friday, January 10, 2014:

Greetings again.
Well, my hopes were dashed. I left the trap that I described originally “just in case…” and my code hit the break point I set in the trap. This means that the underflow occurred despite my implementing the NVIC_PriorityGroupConfig() call.
So this is still open for discussion.

rtel wrote on Friday, January 10, 2014:

I’m struggling with this one. Looking at V7.6.0 the uxPendedTicks variable is only decremented in one place, and it is within a loop that tests to ensure uxPendedTicks is greater than 0, and within a critical section (so assuming interrupt priorities are set correctly, should be safe code).

    while( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U )
        if( xTaskIncrementTick() != pdFALSE )
            xYieldPending = pdTRUE;

The only thing called while the pended ticks are being unwound is xTaskIncrementTick(), so other than xTaskIncrementTick doing something that corrupts uxPendedTicks() it would seem the decrements were safe.

xTaskIncrementTick() manipulates some ready lists, and a couple of file scope variables, but does not attempt to perform any context switching - it is just a C function.

Have you made any edits to the FreeRTOS code anywhere, even if you think they are trivial and could not cause an issue? That is any code in the FreeRTOS/Source directory or sub-directory thereof. The line number you quote above is a return statement that is 18 lines away from the code I posted above.

Did you also define configASSERT()?

Are you able to cut your project down to its bare bones, just enough to still exhibit this behaviour, then send it to me? You can send it to the business contact on I would need the project supplied buildable, so with no absolute file paths, etc.