I am using FreeRTOS to run some tasks in my software. Currently my init task is getting stuck on xQueueSemaphoreTake() function in Queue.c
When I start my program the program runs for a while and then resets and starts with init again. When I see the call stack it shows its stuck on the function i mentioned above. The xQueueSemaphore is invoked while trying to do a blocking receive data from UART peripheral.
In the xQueueSemaphoreTake() function its stuck on portYIELD_WITHIN_API();
I have checked several posts with similiar behavior. I followed their solutions such as stack overflow, or priority setting. I have them all in order.
The configMAX_SYSCALL_INTERRUPT_PRIORITY(5) is number is lower than my UART interrupt(6). I do not have stack issues.
Also when the init task is stuck on the xQueueSemaphore take, the IDLE task is parallely into vApplicationIdleHook() (which i expect is expected behaviour) and then into xPortGetFreeHeapSize() which returns free bytes remaining.
I am new to FreeRTOS and I have exhausted all the solutions online. Can anyone help me?! what could be other possible reasons for this behavior?
Below is the picture of my call stack.
Kindly let me know, if any other details are required.
Is that the intended behaviour, or is the fact in resets the issue?
That is the macro that causes a context switch to another task, so it is expected to be at the top of the call stack - most likely the task is just waiting for the semaphore rather than being stuck in some way.
…so assuming you are using a Cortex-M microcontroller.
From your post it is not clear what problem you are reporting. It sounds like one task is waiting for a semaphore - is the semaphore ever given? What happens if the call to xQueueSemaphoreTake() times out?
Hi Richard, that is not the intended behaviour. Init should be called only once. After that all the tasks should be executed doing context switch.
Yes I am using Cortex-M microcontroller.
Yes one of the task (init task- a high priority task) is waiting for semaphore and doesn’t not acquire it and hence the idle task is running(low priority task).
The xQueueSemaphoreTake() times out and resets and then repeats the same behavior infinitely.
It seems that is the first thing to figure out then - perhaps the resetting and the fact the semaphore is never given are symptoms of the same thing.
Do you know what is causing the reset?
If the code is stuck with obtaining the semaphore and in IDLE task (which only returns the free remaining bytes) triggers watchdog and resets.
So the init task is waiting on the semaphore. What other tasks are interacting with that semaphore?
Why are those tasks not releasing the semaphore?
Once you have answers to those, you’ll likely find the solution to your issue.
There are around 7-8 tasks that run with different priorities from 1 to 5. There are 4 tasks with priority 2 ( which share the UART by time slicing).
The initTask however is highest priority task and is run first and has no time slicing done with other tasks. So initTask should be able to get the semaphore as no other tasks are run before it.
Essentially, initTask is the very first task and only task run so there should not be any contending for the semphore I believe.
Unfortunately belief isn’t enough here. You need to make sure that no other task is run before your init task. Also, make sure that the semaphore has been created before you attempt to take it. check if the semaphore handle is != NULL indicating it has been initialised.
Perhaps try recording a trace of your system, so you can see what is happening with the semaphore and your tasks?
We at Percepio happens to provide such a tool, Tracealyzer for FreeRTOS.
(Excuse the self promotion but it seems pretty motivated in this case.)
I finally found the solution and it wasn’t entirely related to the FreeRTOS sorry. Like @SergentSloGin suggested I checked if the semaphore is created and no other task is run before. Everything in the application and the RTOS was fine.
Like I mentioned the WDOG was triggered and a reset was triggered. Due to this the program again started from initTask. The reason for the WDOG was the timeout. The application was getting timedout waiting for the response from the slave hardware over UART. The task timeout period was not enough. The WDOG timer for the application was only 3s and I wasnt receiving the response from the slaves within 3s.
Hence I increased the task timeouts for the respective tasks and also the WDOG timer to 8s and it works fine.
Thank you all for your help.
I will definitely check out the Tracealyzer @johankraft thanks.
Thanks for taking the time to report back.