The objective of this post is to explain how to check in which core of the ESP32 a certain FreeRTOS task is executing.
Introduction
The objective of this post is to explain how to check in which core of the ESP32 a certain FreeRTOS task is executing.
One of the characteristics of the ESP32 is that it has 2 Tensilica LX6 cores [1], allowing us to run tasks in both CPUs. Note that, when we create a task with the xTaskCreate function, we are not specifying any particular core for it to run. So, FreeRTOS will run the task on the core that is free [2].
As we will see in future examples, we can associate a task to a particular core by using the xTaskCreatePinnedToCore function [3].
For now, we will explain how to check in which core a task is running, in particular, we will analyse it for the setup, main loop and a launched task. To do so, we will use the xPortGetCoreID function.
The code
As usual, the first code in the setup function will be used to open a serial connection, in order for us to print the information about the cores where the tasks are running.
After that, we go straight to getting the information about in which core the setup function is running. As said before, we will use the xPortGetCoreID function to get this information. Note that this function receives no arguments [4], so it needs to be use inside the the task to get the information about the running core.
Serial.begin(112500); delay(1000); Serial.print("Setup: Executing on core "); Serial.println(xPortGetCoreID());
After this, we will launch a new task with the xTaskCreate function, so we can then analyze in which core it will start running. If you need a more detailed explanation on how to use this function to create FreeRTOS tasks, please check this previous tutorial, where the topic is covered in detail.
We will analyze the code for implementing this function later. For now, we will finish the setup function by performing a small delay. This way, we will ensure that the newly created task will run, no matter to which core it is assigned.
Note that this behavior is the expected since the implementation of the ESP32 for the Arduino delay uses the FreeRTOS vTaskDelay function, as can be seen here. So, it means that the task will be blocked during the delay time [5] and the scheduler can attribute the CPU to other free task. Nevertheless, this is only relevant if the newly created task is assigned to the same core where the setup function is executing.
xTaskCreate( genericTask, /* Task function. */ "genericTask", /* String with name of task. */ 10000, /* Stack size in words. */ NULL, /* Parameter passed as input of the task */ 2, /* Priority of the task. */ NULL); /* Task handle. */ delay(2000);
After the setup function, we will specify the main loop. It will only contain a call to the xPortGetCoreID function, so we can know in which core it is running.
void loop() { Serial.print("Main Loop: Executing on core "); Serial.println(xPortGetCoreID()); delay(1000); }
Finally, we will specify the code for the task we launched on the setup function. This will also be very simple and correspond to the execution of that same function, so we can get the core where it is running. Check the full source code bellow.
void setup() { Serial.begin(112500); delay(1000); Serial.print("Setup: Executing on core "); Serial.println(xPortGetCoreID()); xTaskCreate( genericTask, /* Task function. */ "genericTask", /* String with name of task. */ 10000, /* Stack size in words. */ NULL, /* Parameter passed as input of the task */ 2, /* Priority of the task. */ NULL); /* Task handle. */ delay(2000); } void loop() { Serial.print("Main Loop: Executing on core "); Serial.println(xPortGetCoreID()); delay(1000); } void genericTask( void * parameter ){ Serial.print("Created task: Executing on core "); Serial.println(xPortGetCoreID()); vTaskDelete(NULL); }
Testing the code
To test the code just upload it with the Arduino IDE and open the serial console. You should get an output similar to figure 1.
Figure 1 – Output of the program to get the ESP32 execution core of each task.
Note that both the setup and main loop functions are executing on core 1. This is consistent with the implementation of the ESP32 support for the Arduino environment, as can be seen here. The newly created task was assigned to core 0.
Related content
- ESP32 for Arduino
- Use of ESP32 dual core forum thread
- FreeRTOS free tutorial book
- FreeRTOS Reference manual
- ESP32 Arduino installation instructions
References
[1] https://espressif.com/en/products/hardware/esp32/overview
[2] https://www.esp32.com/viewtopic.php?t=764
[3] http://esp32.info/docs/esp_idf/html/dd/d3c/group__xTaskCreate.html
[4] http://esp32.info/docs/esp_idf/html/d2/de2/portable_8h.html#a7e57b592090865283087873469cf866d
[5] http://www.freertos.org/a00127.html
Pingback: ESP32: Running code on a specific core | techtutorialsx
Pingback: ESP32: Running code on a specific core | techtutorialsx
Pingback: ESP32: FreeRTOS counting semaphores | techtutorialsx
Pingback: ESP32: FreeRTOS counting semaphores | techtutorialsx
Pingback: ESP32 | Andreas' Blog
Pingback: ESP32 | Andreas' Blog
Pingback: ESP32 Arduino: Using the pthreads library | techtutorialsx
Pingback: ESP32 Arduino: Using the pthreads library | techtutorialsx