Quando carregamos código no ESP32 usando o Arduino IDE, ele simplesmente roda - não precisamos nos preocupar com qual núcleo executa o código.
Há uma função que você pode usar para identificar em qual núcleo o código está sendo executado:
xPortGetCoreID()
Se você usar essa função em um esboço do Arduino, verá que o setup () e o loop () estão sendo executados no núcleo 1. Teste você mesmo fazendo o upload do seguinte esboço para o seu ESP32.
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
void setup() {
Serial.begin(115200);
Serial.print("setup() running on core ");
Serial.println(xPortGetCoreID());
}
void loop() {
Serial.print("loop() running on core ");
Serial.println(xPortGetCoreID());
}
Criar tarefas
O Arduino IDE suporta o FreeRTOS para o ESP32, que é um sistema operacional em tempo real. Isso nos permite lidar com várias tarefas em paralelo que são executadas de forma independente.
Tarefas são pedaços de código que executam algo. Por exemplo, ele pode estar piscando um LED, fazendo uma solicitação de rede, medindo leituras do sensor, publicando leituras do sensor, etc.
Para atribuir partes específicas de código a um núcleo específico, você precisa criar tarefas. Ao criar uma tarefa, você pode escolher em qual núcleo ela será executada, bem como sua prioridade. Os valores de prioridade começam em 0, em que 0 é a prioridade mais baixa. O processador executará as tarefas com maior prioridade primeiro.
Para criar tarefas, você precisa seguir os próximos passos:
1. Crie um identificador de tarefa. Um exemplo para a Tarefa1:
TaskHandle_t Task1;
xTaskCreatePinnedToCore(
Task1code, /* Function to implement the task */
"Task1", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&Task1, /* Task handle. */
0); /* Core where the task should run */
Void Task1code( void * parameter) {
for(;;) {
Code for task 1 - infinite loop
(...)
}
}
O para (;;) cria um loop infinito. Portanto, essa função é executada de maneira semelhante à função loop () . Você pode usá-lo como um segundo loop no seu código, por exemplo.
Se durante a execução do código você deseja excluir a tarefa criada, você pode usar a função vTaskDelete () , que aceita o identificador de tarefa ( Tarefa1 ) como argumento:
vTaskDelete(Task1);
Codigo de exemplo completo
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
TaskHandle_t Task1;
TaskHandle_t Task2;
// LED pins
const int led1 = 2;
const int led2 = 4;
void setup() {
Serial.begin(115200);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
delay(500);
//create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task2, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
delay(500);
}
//Task1code: blinks an LED every 1000 ms
void Task1code( void * pvParameters ){
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for(;;){
digitalWrite(led1, HIGH);
delay(1000);
digitalWrite(led1, LOW);
delay(1000);
}
}
//Task2code: blinks an LED every 700 ms
void Task2code( void * pvParameters ){
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
for(;;){
digitalWrite(led2, HIGH);
delay(700);
digitalWrite(led2, LOW);
delay(700);
}
}
void loop() {
}