Hi.
I was working in my personal project with ESP32 TTGO T-Display until I stumbled over a problem.
I isolated it and got to know it better, so at this point I think it’s a bug of the library FreeRTOS.
I wanted to have task priority, timer to do the task, and twice this, each in one core. So I ended up creating a task in setup() to run once and program a timer on core 1 and the same for core 0. It works perfectly.
This (each) timer then calls a function (the IRAM_ATTR) that calls the task (pinned to core) I want to call every 1 second, for say. Here I set the priority of this timed function, it seems to work.
The problem is that in the end of this timed task, vTaskDelete doesn’t seem to delete the task and free the resources (I know, it has to have some idle time, but keep up with me). It runs 23 times with a stack size of 10000 words each. Then the xTaskCreatePinnedToCore just returns -1, which is “not enough memory to create the task”.
The solution I could find is to (just once) do a vTaskDelete(of that task). Then after this instruction, the program can execute that task indefinite amount of times. Other solution was to place a vTaskDelete(that timed task) after the task that program the timer in setup().
Here is the code without things that I commented to isolate the problem.
void setup(void)
{
Serial.begin(115200);
xTaskCreatePinnedToCore(
attachInterruptDisplay, /* Function to implement the task */
"attachInterruptDisplay", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
1, /* Priority of the task */
&attachInterrupt_Display, /* Task handle. */
1); /* Core where the task should run */
vTaskDelete(Core_1); //this uncommented XOR that one in the loop uncommented
}
void attachInterruptDisplay(void *parametro) //core 1
{
hw_timer_t *timer1 = NULL;
timer1 = timerBegin(0, 80, true);
timerAttachInterrupt(timer1, &GoCore1, true);
timerAlarmWrite(timer1, 100000, true);
timerAlarmEnable(timer1);
vTaskDelete(attachInterrupt_Display);
} void IRAM_ATTR GoCore1()
{
xTaskCreatePinnedToCore( // função do core 1
Core1, /* Function to implement the task */
"Core1", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
2, /* Priority of the task */
&Core_1, /* Task handle. */
1); /* Core where the task should run */
}
void Core1(void *parameter)
{
debug(String(breakpoint));
breakpoint++;
vTaskDelete(Core_1);
}
void debug(String estado)
{
#ifdef DEBUG_CORE0
if (xPortGetCoreID() == 0)
{
Serial.println();
Serial.println("CORE0: " + estado + String(" ") + String(millis()));
}
#endif
#ifdef DEBUG_CORE1
if (xPortGetCoreID() == 1)
{
Serial.print("CORE1: " + estado + String(" ") + String(millis()) + String(" | "));
}
#endif
}
bool umavez = false;
void loop()
{
if ((millis() > 7000) && (umavez == false))
{
umavez = true;
debug("umavez");
//vTaskDelete(Core_1); //this uncommented XOR that one in the setup() uncommented
}
}