I’m using FreeRTOS 10.3.1 with a STM32H7 MCU and TouchGFX. With a relative high workload, the TouchGFX task will sooner or later just stay in the blocked state. With a debugger I could see some internal task and FreeRTOS statistics:
- According to xPortGetFreeHeapSize, xPortGetMinimumEverFreeHeapSize and vApplicationStackOverflowHook there should be no memory issues.
- In the task handle is a tick variable which holds the next tick to unblock the task. When the fault occurs this tick variable doesn’t change anymore and is less than the current system tick.
- There is no higher priority task which prevents the TouchGFX task from executing, when the fault occurs the idle task is near to 100% run time.
Do you have an idea how to approach this problem?
which port are you using? Your system do not appear to be stuck in the fault handler, so it looks like either a faulty implementtion of the critical section or an irq level miscofiguration, or your application suspends the scheduler with the crktical section claimed.
Thanks for your reply! I’m using the GCC ARM CM4F port. I will check for a wrong irq level configuration. Do you have a FreeRTOS specific irq configuration level in mind or application irq configuration like timer and SPI?
The scheduler should not be suspended, the system is still running and correctly executing even lower priority tasks.
When one task isn’t running, it likely is stuck blocked on some object that isn’t being given. If you look at the tasks stack frame, you can figure out where it is in its code, and what it is blocked on.
I didn’t notice the event object until now. Indeed, the task is blocked on an object.
Edit: The xItemValue is 0xffffffff, so my original post is wrong and this should be the target tick to unblock, correct?
Edit2: Unfortunately the event object is a semaphore used inside the touchgfx library. It blocks for 0xffffffff and is released inside a DMA irq.
So, you have to figure out why the DMA IRQ didn’t happen.
Have you gone through the following pages to make sure you have things like configASSERT() defined, stack overflow checking on, etc.:
Thank you, i checked the mentioned steps and my project should be setup correctly. The interrupt configuration looks good, too.
I found two regular functions using FreeRTOS ISR-Safe function calls and one critical section which takes up to 1 ms (worst case).
This part may not up to date:
" If you are using an STM32 with the STM32 driver library then ensure all the priority bits are assigned to be preempt priority bits by calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before the RTOS is started."
This function and argument doesn’t seem to exist anymore (at least for the STM32H7), instead HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); can be used. However, this is already part of the HAL_Init() function.
Is the task that is staying blocked waiting for this semaphore? Are you able to verify that DMA irq is still firing? What are the values of BASEPRI and PRIMASK registers when the task is no longer getting scheduled?
Yes, the TouchGFX task will not unblock unless the framebuffer semaphore is released. The following cause of events prevents the task from executing
- at some point the DMA interrupt won’t fire anymore
- the framebuffer won’t update without DMA interrupts
- the framebuffer semaphore won’t release without updated framebuffer
- the TouchGFX task will not unblock
As soon as I am able to reproduce this situation, I will read the BASEPRI and PRIMASK registers. My current main objective is to find out why the DMA interrupt stops.
Just in case somone else will face the same problem:
I still don’t know why the DMA interrupts stop, but i found a workaround. When no DMA interrupt was executed for 100 ms, I set the control register bit (DMA2D->CR) to 1. This will start the DMA transfers again.
Thank your reporting your solution.