I use freeRTOS kernal V 10.4.3 with IAR 9.20 on a Cortex M33.
My little project has 3 Tasks, all same priority. Task 1 & 2 have little to do and block by task delay of about 200ms. In idle hook I increment a counter to see no one uses CPU all the time.
Task 3 waits to receive a couple of data from queue (50 entries). Inteerrupt service routine (ISR) gives data by xQueueSendToBackFromISR(). ISR is fired by a port input with a fix square of about 1.2ms.
Normally there were not more than 2 entries in the queue before task 3 gets data out of it. Now and than Task 3 does not get to run and queue gets filled. Idle count still increasing.
When I set a break in the interrupt routine when queue is full I see by task list plug-in that
- Idle: running
- Task 1 & 2: blocked
- Task 3: ready
After some time (few to many 10ms) Tsak 3 gets to run again empties queue in short time.
I assume that no other interrupt does keep CPU busy, as idle would not run either than.
Are there any ideas what the problem might be?
Does your program has long critical sections? Can you try increasing the priority of task 3 and share the result?
I use HAL driver but it seems to me that I do not have long critical section there. In my application I do not have.
I allready tried to increase task priority without any change in the result. Task 1 & 2 seem to run (check by breakpoint).
A reason can be wrong interrupt priorities for interrupts using FreeRTOS API in their corresponding ISRs resp. ISR callbacks.
See e.g. Understanding priority levels of ISR and FreeRTOS APIs - #16 by aggarg for a pretty good explanation.
Did you define configASSERT and also enable stack overflow checking for development/debugging to catch possible fatal errors or data corruption ?
Hi there Hans,
I suggest running your application under Tracealyzer supervision. That will give you a good idea about the interdependencies between your threads of execution along with direct pointers to your problem.
It was the interrupt priority (I should have known). Thanks also for the other hints.
Was it not caught by
No it wasn’t (or I did not realize it?).
I am not used to work with configASSERT. configASSERT is defined by the micro manufacturer, from whom I took the source code to start including the FreeRTOSConfig.h:
#define configASSERT( x ) assert(x)
I was wondering about the vAssertCalled mentioned in the link You gave me. I could not find it anywhere. Where is it expected to be defined?
That definition is correct. I will take a look about what is needed in our M33 port to catch invalid priority configurations.
Just in addition I’m also using C std assert with a GCC/newlib toolchain:
So in FreeRTOSConfig.h I also:
#define configASSERT assert
and define the assert handler (for DEBUG builds) like this to use it with FreeRTOS:
void __assert_func(const char *file, int line, const char *fct, const char *expr)
for( ;; );
vAssertCalled is just an example as mentioned in the configASSERT documentation.