About semaphore deadlock and idle task hook

Hello,

  1. Will the following problems occur in task scheduling? Please confirm.

After the TASK A obtained the Semaphore, it is interrupted by the interrupt execution while executing to release the Semaphore.
But after the interrupt is executed, it jumps to TASK B for execution.
At this time, Task B also needs to obtain the Semaphore.
In this way, Task A and Task B both obtain the same Semaphore resource, forming a deadlock.

  1. Please confirm whether the following result is or not correct.

The project side uses Idle Task hook to execute WDT Clear.
If the above deadlock problem occurs, will it trigger WDT Reset?
The Dummy test found that when TASK A obtains Semaphore but does not release it, and then TASK B obtains Semaphore again, a deadlock will occur.
At this time, it seems that the application tasks are blocked, but the idle task hook is not affected.
Therefore, the expected WDT Reset did not occur.

BR

No, this should not happen. Are you facing a problem? Semaphores are usually meant for inter task synchronization - if the same task is releasing it, you likely want to use mutex.

It is technically not deadlock but starvation - Task B is starved by Task A never releasing the semaphore. This would not impact IDLE task and IDLE task will continue to run if there is no other runnable task.

Thanks for your reply.

Yes, in order to prevent the same resource from being used by different tasks at the same time, Semaphore is used as a mutex.
Now there is a bug, and the cause seems to be determined to be caused by this problem.
Is there any logic control in the FreeRTOS kernel that will prevent the execution of tasks from switching? Please confirm.

In this case, both task A and task B cannot obtain Semaphore and are blocked.
Can this be considered a deadlock?
I would like to ask, how to prevent this problem from happening or how to recover after it happens? Please confirm.
The original idea was to restore it through WDT Reset, but in this case the Idle task is not affected, and then WDT does not work.

BR

Tasks stuck waiting for a mutex don’t use any CPU time, so won’t block the idle task, and thus not affect your watchdog. Just always kicking the watchdog in the idle task does not verify that your program isn’t stuck, it just says that no task is just using up all the CPU time. You generally need ever “important” task to periodically do something visible to the watchdog kicker, that it can make sure everyone is making progress.

As to your “Deadlock” question, it doesn’t sound like what you are describing is what is normally considered to be a deadlock, just some bug that made somebody not release a resource. The normal thing called “Deadlock”, is where task A get resource A, and then tries to get resource B, but can’t because task B has that resource, but it can’t finish to release it because now it needs resource A, but A won’t free that until it gets resource B.

My preferred solution to your problem, is not to use an infinite block, especially if you are holding a resource, but to block with a definite timeout, and if you reach that timeout you need to “abort” your operation and give back your resources.

Another rule that eliminates the problem, is to figure out an order for your resources, and you must never go backwards in that order in requesting, so if one task does A before B, no task can do B then A, but if it might need A, it takes it before taking B.

Assuming that you mean you are using xSemaphoreCreateMutex API, you are good.

Are you disabling interrupts in your application like calling taskENTER_CTRITICAL?

@richard-damon has already pointed the flaw in your Watchdog implementation and a potential solution.

Try to remove other logic from your tasks and increment a variable or blink an LED and see if those are getting scheduled.

No, the xSemaphoreCreateMutex API is not used.
The Semaphore being used is a counting semaphore used for resource management.

Disable interrupts are used in the application, such as calling "CPSID I ". I think disabling interrupts has little to do with task scheduling.

Disabling Interrupts does a LOT about task scheduling, as without the tick interrupt, time doesn’t pass.

Note that a mutex is the right tool to protect resources. I’d propose to use it instead of a counting semaphore, which is or should be used to count and signal events.