Need help with semaphore handling

User avatar
MickPF
Posts: 63
Joined: Tue Apr 03, 2018 8:47 pm

Need help with semaphore handling

Postby MickPF » Thu Jul 16, 2026 6:09 pm

Hello,

in my programming, I need a semaphore so that only one FreeRTOS task can access the SPI resource at a time, and the others wait until it becomes available.

During the testing phase, I do not use any tasks, and only one procedure calls the "task()" function.

This is the relevant part of my code:

Code: Select all

#if defined(CONFIG_SEMAPHORE_TYPE_FREERTOS)
#include "freertos/semphr.h"

SemaphoreHandle_t   semaphore_spi;
#elif defined(CONFIG_SEMAPHORE_TYPE_POSIX)
#include <semaphore.h>

sem_t               semaphore_spi;
#endif

...

esp_err_t init()
{
    esp_err_t   ret = ESP_OK;

#if defined(CONFIG_SEMAPHORE_TYPE_FREERTOS)
    if ((semaphore_spi = xSemaphoreCreateMutex()) == NULL)
    {
        ESP_LOGE(MODULE_TAG, "ERROR: Creating semaphore for SPI%d_HOST failed", interface->spi->spi_host + 1);
        return(ESP_FAIL);
    }
#elif defined(CONFIG_SEMAPHORE_TYPE_POSIX)
    if ((ret = sem_init(&semaphore_spi, 1, 1)) != NO_ERROR)
    {
        ESP_LOGE(MODULE_TAG, "ERROR: Creating semaphore for SPI%d_HOST failed, ret = %d",
                 interface->spi->spi_host + 1, ret);
        return(ret);
    }
#endif
}

esp_err_t task()
{
    esp_err_t   ret = ESP_OK;

#if defined(CONFIG_SEMAPHORE_TYPE_FREERTOS)
    if (xSemaphoreTake(semaphore_spi, pdMS_TO_TICKS(1000)) == pdTRUE)
#elif defined(CONFIG_SEMAPHORE_TYPE_POSIX)
    if ((ret = sem_wait(&semaphore_spi)) == NO_ERROR)
#endif
    {
        ...
#if defined(CONFIG_SEMAPHORE_TYPE_FREERTOS)
        xSemaphoreGive(semaphore_spi);
#elif defined(CONFIG_SEMAPHORE_TYPE_POSIX)
        sem_post(&semaphore_spi);
#endif
    }
    else
    {
        ESP_LOGE(MODULE_TAG, "ERROR : xSemaphoreTake failed");
#if defined(CONFIG_SEMAPHORE_TYPE_FREERTOS)
        ret = ESP_FAIL;
#endif
    }
    return(ret);
    }
}

Creating semaphore works flawlessly in both FreeRTOS („xSemaphoreCreateBinary()“ and „xSemaphoreCreateMutex()“) and POSIX („sem_init()“) versions.
However, the call to "xSemaphoreTake()" with semaphore created by the call „xSemaphoreCreateBinary()“ always returns pdFALSE!
The call to "xSemaphoreTake()" with semaphore created by the call „xSemaphoreCreateMutex()“ and the call to "sem_wait()" hang.

What am I doing wrong?
Does anyone have experience using semaphores with ESP-IDF?
Can anyone help me?

Thanks in advance

nopnop2002
Posts: 359
Joined: Thu Oct 03, 2019 10:52 pm
Contact:

Re: Need help with semaphore handling

Postby nopnop2002 » Fri Jul 17, 2026 12:16 am

It seems you are confusing semaphores and mutexes.

To use a semaphore, you initialize it with `xSemaphoreCreateBinary()`, whereas for a mutex, you use `xSemaphoreCreateMutex()`; however, the semaphore values ​​differ after initialization.

A mutex has an initial value of 1, and you must "take" it before using the resource you wish to protect.
In contrast, a semaphore has an initial value of 0, and you "give" it when passing control to another task.

Code: Select all

#include "stdio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

void app_main(void)
{
    SemaphoreHandle_t xSemaphore1;
    SemaphoreHandle_t xSemaphore2;

    UBaseType_t value;
    xSemaphore1 = xSemaphoreCreateBinary();
    configASSERT( xSemaphore1 );
    value = uxSemaphoreGetCount( xSemaphore1 );
    printf("xSemaphoreCreateBinary=%d\n",(int)value);
    xSemaphoreGive(xSemaphore1);
    value = uxSemaphoreGetCount( xSemaphore1 );
    printf("xSemaphoreCreateBinary=%d\n",(int)value);

    xSemaphore2 = xSemaphoreCreateMutex();
    configASSERT( xSemaphore2 );
    value = uxSemaphoreGetCount( xSemaphore2 );
    printf("xSemaphoreCreateMutex=%d\n",(int)value);
    if (xSemaphoreTake(xSemaphore2, pdMS_TO_TICKS(1000)) == pdTRUE) {
        printf("xSemaphoreTake success\n");
        value = uxSemaphoreGetCount( xSemaphore2 );
        printf("xSemaphoreCreateMutex=%d\n",(int)value);
    } else {
        printf("xSemaphoreTake fail\n");
    }
}

Who is online

Users browsing this forum: Amazon [Bot] and 2 guests