xTaskGetTickCount not incrementing

seek25 wrote on Monday, April 04, 2016:


I am having some issues with Cortex-M4 and FreeRTOS 7.3.0, 4 tasks and 1 interrupt handler.

Basicalyl I am stressing the board by sending patterns of data over 8 inputs that are configured to generate an interrupt and they all share teh same handler. The interrupts are generated 20uS apart and the lines are toggled at random.

The issue is that after an amount of time and data sent, say 10k samples or less, the content switchig is no longer happening. Being able to set a breakpoint on a task that had a call to xTaskGetTickCount the returned number was all the time the same. I wasn’t looking into FreeRTOS sources but if a counter is supposed to overflow in order to generate an interrupt that will awake the scheduler then that won;t happen.

The aplication does not hang, it’s just the task is not switching. I have the stack overflow handler in place and it’s not getting called.

Any idea what could cause a situation like the above, what is the mechanism that increases tick count, I remember reading about it but can’t recall at this time. What I would like to know is what kind of exception can causes it to stop working.



edwards3 wrote on Monday, April 04, 2016:

Normally the answer is interrupt priorities are set wrong, which is why new versions of freeRTOS have lots of assert calls to trap that. Your version is old though and I dont know how many asserts it has for this config problem. See

seek25 wrote on Tuesday, April 05, 2016:

Could you please elaborate on how the interrupts priorities can be set wrong and how this would affect FreeRTOS tick count not being incremented and a singel task in run forever in a loop with no context switch?


rtel wrote on Tuesday, April 05, 2016:

The Cortex-M port implements a full interrupt nesting model where
critical sections leave a subset of interrupts enabled at all times.
The interrupts that are enabled at all times are not effected by
anything the RTOS code is doing, and continue to execute even when the
RTOS code is inside a critical section. That means an interrupt that is
never disabled cannot make use of the RTOS API, because to do so can
result in corruption of RTOS data if the handler executes while the RTOS
code is in a critical section. If the data is corrupted anything can
happen, and typically a symptom would be something like you are reporting.

The way interrupt priorities work on Cortex-M devices is complex (did
you read the link already posted?), but FreeRTOS makes it very easy to
trap getting this wrong. Simply define configASSERT(), and if you are
using a version of FreeRTOS created in the last couple of years, the
code will hit the assert if an interrupt tries to access a FreeRTOS API
function from an invalid priority.

seek25 wrote on Tuesday, April 05, 2016:

If I read that right there should be any issue if the interrupt coed is not using any RTOS calls, is that right?

In my case the interrupt code is not calling any function at all, just manipulates some volatile variables.

This is how the FreeRTOS.h looks at the end of it, about config asert you have requested, seems to be in place

/* Normal assert() semantics without relying on the provision of an assert.h
header file. */

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ) __asm volatile( "NOP" ); }

#endif /* FREERTOS_CONFIG_H */

edwards3 wrote on Tuesday, April 05, 2016:

If none of the interrupts use the rtos API then that should not be the root cause.

seek25 wrote on Tuesday, April 05, 2016:

I have reviewed the code and I see the interrupt code calls FreeRTOS api, have not noticed that ebfore due name of the function

void pin_edge_handler(const uint32_t sourceid, const uint32_t mask){  
  ProcessInterrupt(sourceid, mask);

That was writen and forgotten to be removed, at that time I would not know if the FreeRTOS can switch context while interrupt code was running, that should have not happened under any circumstances, the interrupt code must run regardless of anything else.

Now that seems redundant as the interrupt is highest priority and would interrupt FreeRTOS anyway, could that be the cause and if yes can you explain that scenario.


rtel wrote on Wednesday, April 06, 2016:

If that function was called from an interrupt has a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY (which if this is a Cortex-M, means
a numeric priority value that is lower), then yes that could definitely
be the cause as already explained.

Also, if this is called from an ISR, then normally taskENTER_CRITICAL()
and taskEXIT_CRITICAL() are not the right macros to use, but if this is
a Cortex-M then it is probably ok.

seek25 wrote on Wednesday, April 06, 2016:

Yes, it was called from an ISR with priority 0, the highest.

I take such interrupt will never be interrupted by FreeRTOS.

In your code, do you disable all interrupts or just those with lower priority than scheduler runs at? The point ehre is that under no circumsnatnces anything should stop pin edge interrupt.

Also, since the pind edge interrupt running at the highest, 0, priority, I would suspect that calling taskEnter and taskExit are pointless, durring interrupt execution the kernel scheduler won’t get a chance to execute and has to wait for interrupt to finish it first. But if I set the pin edge interrupt priority to a lower value (which translates into a higher number for Cortex-M4) then it would make sense to have taskEnter/exit calls to prevent the scheduler from switching whilst interrupt code executes. Please correct me if I’m wrong.


rtel wrote on Wednesday, April 06, 2016:

See the following link http://www.freertos.org/a00110.html#kernel_priority

seek25 wrote on Wednesday, April 06, 2016:

Thanks, that looks useful, I take it’s still relevant for older version like the one I use, not sure if you do add version change pointers to the documentation to notify about a feature that it’s available starting version X or was changed, discontinued, etc.

I am considering purchasing the paid version of the OS, the technical documentation is the same or better? I currently find very difficult to find details about anythig as there seems not to be a proper user manual just the site with a few links and a page or less about various stuff.