freeRTOS Semaphore problem

Hello everyone, I am currently trying to use FreeRTOS. I want the energySaving task to call uploadData and MQTT first. However, I keep encountering an “assert failed: xQueueSemaphoreTake queue.c:1653 (( pxQueue ))” error when using Semaphore. I tried commenting out uploadData and MQTT, and it runs successfully if they are commented out. I would like to know what could be causing this issue.

void TaskUploadData(void *pvParam) {
  while (1) {
    HTTPClient http;
    if (xSemaphoreTake(semStart, portMAX_DELAY) == pdTRUE){
      Serial.println("HTTP");
      String tmpurl = (url + apiKey) + "&field1=" + String(tempB, 1) + "&field2=" + String(rh) + "&field3=" + String(int(soilH)) + "&field4=" + String(pm1) + "&field5=" + String(pm25) + "&field6=" + String(pm10) + "&field7=" + String(pressure);
      http.begin(tmpurl);
      http.GET();
      http.end();
      xSemaphoreGive(semUpload);
    }
  }
  //上傳資料至Thingspeak,可依照Field不同調整tmpurl中的順序,時間可在最後vTaskDelay調整
  //最上方預留2秒給其他感應器讀取數據,同時確保有讀取到資料才上傳,若溫度與濕度為0則不上傳(尚未讀取到資料)
  //!因Thingspeak限制資料傳輸間隔最少需要15秒,因此下方至少需13000(加上方2000)才可達到15秒間隔!
}
void TaskMQTT(void *pvParam) {
  MQTTClient.setServer(MQTTServer, MQTTPort);
  while (1) {
    if (xSemaphoreTake(semStart, portMAX_DELAY) == pdTRUE){
      Serial.println("MQTT");
      if (!MQTTClient.connected()) {
        Serial.println("MQTT connecting");
        vTaskSuspend(lowBatt);
        while (!MQTTClient.connected()) {
          MQTTClient.connect(clientID);
          vTaskDelay(100 / portTICK_PERIOD_MS);
        }
        Serial.println("MQTT Connected!");
        vTaskResume(lowBatt);
      }
      if (MQTTClient.connected()) {
        MQTTClient.publish("HomeSenser/esp32/temp", String(tempB).c_str());
        MQTTClient.publish("HomeSenser/esp32/rh", String(rh).c_str());
        MQTTClient.publish("HomeSenser/esp32/soilH", String(soilH).c_str());
        MQTTClient.publish("HomeSenser/esp32/pm1", String(pm1).c_str());
        MQTTClient.publish("HomeSenser/esp32/pm25", String(pm25).c_str());
        MQTTClient.publish("HomeSenser/esp32/pm10", String(pm10).c_str());
        MQTTClient.publish("HomeSenser/esp32/pressure", String(pressure).c_str());
        MQTTClient.publish("HomeSenser/esp32/SolarTemp", String(tempSolar).c_str());
        MQTTClient.publish("HomeSenser/esp32/battV", String(battV).c_str());
        MQTTClient.publish("HomeSenser/esp32/battA", String(battA).c_str());
        MQTTClient.publish("HomeSenser/esp32/battW", String(battW).c_str());
        xSemaphoreGive(semMqtt);
      }
    }
  }
}
void energySaving(void *pvParam) {
  esp_wifi_set_ps(WIFI_PS_NONE);
  while (1) {
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    xSemaphoreGive(semStart);
    xSemaphoreTake(semMqtt, portMAX_DELAY);
    xSemaphoreTake(semUpload, portMAX_DELAY);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    esp_sleep_enable_timer_wakeup(13500000);  //13.5秒
    Serial.println("進入 Light Sleep 模式");
    Serial.flush();
    esp_light_sleep_start();
  }
}
//WiFi計時器,若超過三分鐘未連線則重啟動
void wifiRestart(TimerHandle_t xTimer) {
  esp_restart();
}

void setup() {
  Serial.begin(115200);
  xTaskCreate(TaskReadPMS, "Read PMS Sensor", 1500, NULL, 1, NULL);      //使用904
  xTaskCreate(TaskReadSoilrh, "Read Soil Sensor", 1200, NULL, 2, NULL);  //使用852
  xTaskCreate(TaskReadBMP, "Read BMP180", 1800, NULL, 2, NULL);          //使用1244
  xTaskCreate(TaskReadTemp, "Read Solar Temp ", 2000, NULL, 2, NULL);
  xTaskCreate(TaskReadINA, "Read INA226 ", 3000, NULL, 2, NULL);
  xTaskCreate(TaskWiFi, "WiFi connect", 3000, NULL, 1, NULL);  //使用1856

  xTaskCreatePinnedToCore(TaskUploadData, "Upload Data", 5500, NULL, 2, &uploadData, 0);  //使用3204
  xTaskCreatePinnedToCore(TaskMQTT, "MQTT Service", 4000, NULL, 2, &mqtt, 0);             //使用1452
  xTaskCreatePinnedToCore(energySaving, "Energy Saving", 4000, NULL, 1, &lowBatt, 0);     //使用1856

  vTaskSuspend(lowBatt);
  timer = xTimerCreate("WiFi connection timer", (180000 / portTICK_PERIOD_MS), pdFALSE, (void *)1, wifiRestart);

  semStart = xSemaphoreCreateBinary();  // 用來控制 B 和 C 是否可以開始
  semMqtt = xSemaphoreCreateBinary();    // 控制 B 任務
  semStart = xSemaphoreCreateBinary();   // 控制 C 任務

  delay(1000);
}

Seems that semStart is not yet created when TaskUploadData tries to use it.
You should ensure that all resources like semaphores, queues etc. are successfully created before they are used.

As @hs2 explained, you are using semaphore before creating it. Move the calls to xSemaphoreCreateBinary up in the setup function:

void setup() {
  Serial.begin(115200);

  semStart = xSemaphoreCreateBinary();  // 用來控制 B 和 C 是否可以開始
  semMqtt = xSemaphoreCreateBinary();    // 控制 B 任務
  semStart = xSemaphoreCreateBinary();   // 控制 C 任務

  xTaskCreate(TaskReadPMS, "Read PMS Sensor", 1500, NULL, 1, NULL);      //使用904
  xTaskCreate(TaskReadSoilrh, "Read Soil Sensor", 1200, NULL, 2, NULL);  //使用852
  xTaskCreate(TaskReadBMP, "Read BMP180", 1800, NULL, 2, NULL);          //使用1244
  xTaskCreate(TaskReadTemp, "Read Solar Temp ", 2000, NULL, 2, NULL);
  xTaskCreate(TaskReadINA, "Read INA226 ", 3000, NULL, 2, NULL);
  xTaskCreate(TaskWiFi, "WiFi connect", 3000, NULL, 1, NULL);  //使用1856

  xTaskCreatePinnedToCore(TaskUploadData, "Upload Data", 5500, NULL, 2, &uploadData, 0);  //使用3204
  xTaskCreatePinnedToCore(TaskMQTT, "MQTT Service", 4000, NULL, 2, &mqtt, 0);             //使用1452
  xTaskCreatePinnedToCore(energySaving, "Energy Saving", 4000, NULL, 1, &lowBatt, 0);     //使用1856

  vTaskSuspend(lowBatt);
  timer = xTimerCreate("WiFi connection timer", (180000 / portTICK_PERIOD_MS), pdFALSE, (void *)1, wifiRestart);

  delay(1000);
}





In addition it’s good habit and better to check the status/error return values of the FreeRTOS (create) calls.