Skip to main content
Graduate
May 16, 2025
Solved

FREERTOS: Binary-Semaphore initial state bug

  • May 16, 2025
  • 4 replies
  • 952 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.

    This topic has been closed for replies.
    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

    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
    Graduate
    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.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
    Graduate
    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
    }