Como usar os dois nucleos do ESP32 o Arduino IDE

Eletrônica

O ESP32 vem com 2 microprocessadores LX6 de 32 bits Xtensa: núcleo 0 e núcleo 1. Então, é dual core. Quando executamos código no Arduino IDE, por padrão, ele é executado no núcleo 1. Nesta postagem, mostraremos como executar o código no segundo núcleo do ESP32 criando tarefas. Você pode executar pedaços de código simultaneamente em ambos os núcleos e fazer sua multitarefa ESP32.

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());
}
Abra o Serial Monitor com uma taxa de transmissão de 115200 e verifique o núcleo no qual o esboço do Arduino está sendo executado.


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 */
3. Depois de criar a tarefa, você deve criar uma função que contenha o código para a tarefa criada. Neste exemplo, você precisa criar a função Task1code () . Veja como a função tarefa se parece:
Void Task1code( void * parameter) {
  for(;;) {
    Code for task 1 - infinite loop
    (...)
  }
}

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() {
  
}










Fonte
https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/#more-74416
Mais Dicas