Please help is possible:
I have an application running with several FreeRTOs tasks.
Everything works very well.
However, there is one observation that I cannot understand why.
void SetupCoreTasks(){
xTaskCreatePinnedToCore(v_VerificaWifi, "v_VerificaWifi", MEM_v_VerificaWifi, NULL, tskIDLE_PRIORITY + 1, &Handle_VerificaWifi, 1);
if (Display.Sinal){xTaskCreatePinnedToCore(v_SinalWifi, "v_SinalWifi", MEM_v_SinalWifi, NULL, tskIDLE_PRIORITY + 1, &Handle_SinalWifi, 1);}
xTaskCreatePinnedToCore(v_DataHora, "v_DataHora", 1800, NULL, tskIDLE_PRIORITY + 1, &Handle_DataHora, 0);
xTaskCreatePinnedToCore(v_DisplayHora, "v_DisplayHora", 2000, NULL, tskIDLE_PRIORITY + 1, &Handle_DisplayHora, 0);
xTaskCreatePinnedToCore(v_Alarme, "v_Alarme", MEM_Alarme, NULL, tskIDLE_PRIORITY + 1, &Handle_Alarme, 0);
if (Display.Uptime) {xTaskCreatePinnedToCore(v_DisplayUptime, "v_DisplayUptime", 1500, NULL, tskIDLE_PRIORITY, &Handle_DisplayUptime, 0);}
if (DataLogger_.Ativar) {
xTaskCreatePinnedToCore(v_Datalogger, "v_Datalogger", 3000, NULL, tskIDLE_PRIORITY + 1, &Handle_Datalogger, 0);
StatusSDCard(true);
}else{
StatusSDCard(false);
}
if(mqtt.ATIVAR){
xTaskCreatePinnedToCore(v_MQTT, "v_MQTT", 8000, NULL, tskIDLE_PRIORITY + 1, &Handle_MQTT, 1);
xTaskCreatePinnedToCore(v_MQTT_Conn, "v_MQTT_Conn", 8000, NULL, tskIDLE_PRIORITY + 1, &Handle_MQTT_Conn, 1);
}
if (Display.Memoria){
//xTaskCreatePinnedToCore(v_PrintTask, "v_PrintTask", 1800, NULL, tskIDLE_PRIORITY, &Handle_PrintTask, tskNO_AFFINITY);
delay(3000);
xTaskCreatePinnedToCore(v_PrintMem, "v_PrintMem", 3000, NULL, tskIDLE_PRIORITY, &Handle_PrintMem, tskNO_AFFINITY);
}
if (DataLogger_.Restart){
xTaskCreatePinnedToCore(v_RotinaRestart, "v_RotinaRestart", 1600, NULL, tskIDLE_PRIORITY, &Handle_PrintMem, tskNO_AFFINITY);
}
}
void v_PrintMem(void *parameters) {
static uint32_t mh = UINT32_MAX;
while(1){
uint32_t min_heap_atual = esp_get_free_heap_size();
uint32_t min_heap = esp_get_minimum_free_heap_size();
Serial.printf("Memoria atual: %d, Menor valor: %d\n", min_heap_atual, min_heap);
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
I am performing several tasks and this consumes certain memory, as I am monitoring it on the serial monitor.
The problem is the following:
When a certain task is performed and then deleted, for example an alarm. The memory that was free does not return to being exactly what it was, it always returns a little smaller.
Free memory after starting: 73740
The memory is free after executing the task of blinking the LED and having the task deleted: 72168
void v_Alarme(void *parameters) {
UBaseType_t uxHighWaterMark;
float tempReceived;
while (1) {
xQueueReceive(TempC_Queue, &tempReceived, portMAX_DELAY);
if ((tempReceived < alarme.Inicio || tempReceived > alarme.Fim) && alarme.AlarmeEnviado == false) {
if (alarme.Email) {
int msg = 2;
xTaskCreatePinnedToCore(v_EnviaEmail, "v_EnviaEmail", 10000, (void *)&msg, tskIDLE_PRIORITY + 2, &Handle_EnviaEmail, 1);
}
if (alarme.Led) {xTaskCreate(v_PiscaLed, "v_PiscaLed", MEM_PiscaLed, NULL, tskIDLE_PRIORITY + 1, &Handle_PiscaLed);}
if (alarme.Sonoro) {xTaskCreate(v_AlertaSonoro, "v_AlertaSonoro", MEM_AlertaSonoro, NULL, tskIDLE_PRIORITY + 1, &Handle_AlertaSonoro);}
if (alarme.WebHook) {
if (validarWebHook()){
xTaskCreate(v_WebHook, "v_WebHook", MEM_WebHook, NULL, tskIDLE_PRIORITY + 1, &Handle_WebHook);
} else {
xTaskCreate(vStatusError, "v_StatusError", 3000, (void *)true, 2, NULL);
}
}
alarme.AlarmeEnviado = true;
xTaskCreate(v_AlarmeEnviado, "v_AlarmeEnviado", MEM_AlarmeEnviado, NULL, 1, &Handle_AlarmeEnviado);
}else if (tempReceived >= alarme.Inicio && tempReceived <= alarme.Fim) {
if (Handle_PiscaLed != NULL) {
xSemaphoreTake(xMutexLed, portMAX_DELAY);
vTaskDelete(Handle_PiscaLed);
Handle_PiscaLed = NULL;
digitalWrite(Led1, HIGH);
alarme.AlarmeEnviado=false;
xSemaphoreGive(xMutexLed);
}
if (Handle_AlertaSonoro != NULL) {
xSemaphoreTake(xMutexSonoro, portMAX_DELAY);
digitalWrite(Sonoro1, LOW);
vTaskDelete(Handle_AlertaSonoro);
Handle_AlertaSonoro = NULL;
alarme.AlarmeEnviado=false;
xSemaphoreGive(xMutexSonoro);
}
}
vTaskDelay(900 / portTICK_PERIOD_MS);
}
}
void v_AlarmeEnviado(void *pvParameters) {
TickType_t now;
now = xTaskGetTickCount();
vTaskDelayUntil(&now,pdMS_TO_TICKS(alarme.Intervalo));
alarme.AlarmeEnviado=false;
vTaskDelete(NULL);
}
void v_PiscaLed(void *parameters){
while(1){
xSemaphoreTake(xMutexLed, portMAX_DELAY);
digitalWrite(Led1, HIGH);
xSemaphoreGive(xMutexLed);
vTaskDelay(500 / portTICK_PERIOD_MS);
xSemaphoreTake(xMutexLed, portMAX_DELAY);
digitalWrite(Led1, LOW);
xSemaphoreGive(xMutexLed);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void v_AlertaSonoro(void *parameters){
while(1){
xSemaphoreTake(xMutexSonoro, portMAX_DELAY);
digitalWrite(Sonoro1, HIGH);
xSemaphoreGive(xMutexSonoro);
vTaskDelay(500 / portTICK_PERIOD_MS);
xSemaphoreTake(xMutexSonoro, portMAX_DELAY);
digitalWrite(Sonoro1, LOW);
xSemaphoreGive(xMutexSonoro);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
As you can see, the task was created and after returning to normal conditions it was deleted. However, the memory never becomes as free as it once was…even after a long time.
What is this problem? Why do MCU and FreeRTOs behave this way?
The problem this causes is that after a long run time, the memory becomes so low that it restarts and causes a stackoverflow.




