Skip to main content
Associate III
May 16, 2025
Solved

FREERTOS: Binary-Semaphore initial state bug

  • May 16, 2025
  • 4 replies
  • 954 views

Hello Experts,

i am facing a similar issue on the STM32F407G discovery board. Is there any solution or a temporary fix for this iisue?

https://community.st.com/t5/stm32cubemx-mcus/re-freertos-semaphore-not-initialised-correctly-by-cubemx/td-p/780252

 

Changing the initial state of the semaphore to Depleted does nothing in the semaphore definition and creation:

ak52_1-1747402483298.png

In freertos.c, inside the function MX_FREERTOS_Init(). i  think the second function parameter should be zero

ak52_2-1747402578968.png

 

I am trying a simple GPIO interrupt to task signaling, but the task always takes a semaphore without the GPIO interrupt the first time. I have attached the complete freertos.c file for context. This is the console screenshot to highlight the bug:

ak52_4-1747403494153.png

 

 

I tried to manually change:

myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);

to

myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 0);

Now the task does not take the semaphore during start up, but the moment the GPIO interrupt occurs(push-button), the whole system hangs in an asset failure:

ak52_3-1747403159242.png

Is there any solution to this problem? I have attached my freertos.c file as well.

Best answer by Pavel A.

Is config_USE_COUNTING_SEMAPHORES defined as 1 ?

Maybe, change osSemaphoreCreate  like following:

...........
 if (count == 1) {
 return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
 }
 else if (count == 0) {
 sema = xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
 if (!sema) return sema;
 osSemaphoreWait(sema, 0); //immediately take it
 return sema;
 }
 else {
..........

 

4 replies

Pavel A.
Super User
May 16, 2025

If the 2nd parameter is 0, osSemaphoreCreate likely returned NULL handle (myBinarySem01Handle ), this is why you assert in xQueueGiveFromISR. Please see the source in cmsis_os.c and you will understand.

 

ak52Author
Associate III
May 16, 2025

Yes, thanks for pointing it out. Looking at osSemaphoreCreate  function i realized it was returning NULL.

ak52_0-1747423945047.png

This brings up the question how do we change the semaphores initial state to depleted/empty?

I also tried to use the native FreeRTOS APIs (xSemaphoreCreateBinary) which creates the semaphore in an 'empty' state, this worked for me, so i am pretty confident there is some issue in the cmsis implementation.

Pavel A.
Pavel A.Best answer
Super User
May 16, 2025

Is config_USE_COUNTING_SEMAPHORES defined as 1 ?

Maybe, change osSemaphoreCreate  like following:

...........
 if (count == 1) {
 return xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
 }
 else if (count == 0) {
 sema = xSemaphoreCreateBinaryStatic( semaphore_def->controlblock );
 if (!sema) return sema;
 osSemaphoreWait(sema, 0); //immediately take it
 return sema;
 }
 else {
..........

 

ak52Author
Associate III
May 19, 2025

Thanks , you solution worked. But i used it in a different way, I did not want to modify the HAL function as it overwrites every time there is a change in the .ioc file

So i did something like this:

osSemaphoreId bin_sem_id;
osSemaphoreDef(bin_sem);

bin_sem_id = osSemaphoreCreate(osSemaphore(bin_sem), 1);

if (bin_sem_id != NULL) 
{
 osSemaphoreWait(bin_sem_id, 0); // Take the semaphore immediately (no blocking)
 // Now the semaphore has a count of 0 and is unavailable.
} 
else 
{
 // Semaphore creation failed
}