Semaphored give is mistake

I would like some help.

I’m having trouble with a semaphored,

Why is semaphoro blocking the resource? Why isn’t he releasing the resource with give ?

void v_AlarmeTempLed(void *parameters) {
    float tempReceived;
    //TaskHandle_t Handle_PiscaLed = NULL;
    while (1) {
        if (xQueueReceive(TempC_Queue, &tempReceived, portMAX_DELAY) == pdPASS) {
            if (tempReceived < alarme.Inicio || tempReceived > alarme.Fim) {
                if (Handle_PiscaLed == NULL) {
                    Serial.println("Entrei na criação da tarefa...");
                    xTaskCreate(v_PiscaLed, "v_PiscaLed", 4096, NULL, tskIDLE_PRIORITY + 1, &Handle_PiscaLed);
                }
            } else if (tempReceived >= alarme.Inicio && tempReceived <= alarme.Fim) {
                Serial.println("Temperatura Correta");
                if (Handle_PiscaLed != NULL) {
                    if (xSemaphoreTake(xMutexLed, portMAX_DELAY)) {
                        Serial.println("Vou deletar a tarefa....");
                        LigaLed(2,false);
                        vTaskDelete(Handle_PiscaLed);
                        Handle_PiscaLed = NULL; // Redefinir o identificador
                        xSemaphoreGive(xMutexLed);
                    }
                }
            }
        }
        vTaskDelay(1500 / portTICK_PERIOD_MS);
    }
}

void v_PiscaLed(void *parameters){
      while(1){
          if (xSemaphoreTake(xMutexLed, 100)) {
              digitalWrite(Led1, HIGH);
              vTaskDelay(500 / portTICK_PERIOD_MS);
              digitalWrite(Led1, LOW);
              vTaskDelay(500 / portTICK_PERIOD_MS);
              digitalWrite(Led1, HIGH);
              Serial.print(".");
              xSemaphoreGive(xMutexLed);              
          } 
      }
}

the impression I have is that give does not work for the other task to release processing.

Where am I going wrong?

He took a long time to be released, what must be happening?

why are you dynamically recreating and deleting your led task? No need to do that and a lot of deadlock potential.

Reading your code, it seems that you want to -

  1. Start blinking an LED when out of range temperature is detected.
  2. Stop blinking the same LED when the temperature is back in range.

As @RAc pointed, you do not need to create and delete task for that. One way to do that is to use event groups -

EventGroupHandle_t eventGroup;

#define TEMPERATURE_BIT ( 1 << 0 )

void v_AlarmeTempLed(void *parameters) {
    float tempReceived;
    // Create event group here or somewhere else.
    eventGroup = xEventGroupCreate();
    // Create v_PiscaLed here or somewhere else.
    xTaskCreate(v_PiscaLed, "v_PiscaLed", 4096, NULL, tskIDLE_PRIORITY + 1, NULL);

    while (1) {
        if (xQueueReceive(TempC_Queue, &tempReceived, portMAX_DELAY) == pdPASS) {
            if (tempReceived < alarme.Inicio || tempReceived > alarme.Fim) {
                Serial.println("Entrei na criação da tarefa...");
                xEventGroupSetBits(eventGroup, TEMPERATURE_BIT);
            } else if (tempReceived >= alarme.Inicio && tempReceived <= alarme.Fim) {
                Serial.println("Temperatura Correta");
                xEventGroupClearBits(eventGroup, TEMPERATURE_BIT);
            }
        }
        vTaskDelay(1500 / portTICK_PERIOD_MS);
    }
}

void v_PiscaLed(void *parameters){
      while(1){
          if (xEventGroupWaitBits(eventGroup,
                                  TEMPERATURE_BIT,
                                  pdFALSE, // Do not clear so that we continue blinking until v_AlarmeTempLed task us to stop.
                                  pdTRUE,
                                  portMAX_DELAY)) {
              digitalWrite(Led1, HIGH);
              vTaskDelay(500 / portTICK_PERIOD_MS);
              digitalWrite(Led1, LOW);
              vTaskDelay(500 / portTICK_PERIOD_MS);
              digitalWrite(Led1, HIGH);
              Serial.print(".");
          } 
      }
}
1 Like

Solved!,

Very much Tanks