Включаем два ядра на работу в микроконтроллере SP32 в среде программирования Arduino IDE.

Страница на этапе разработки

Платы микроконтроллеров ESP32 выпускаются с двумя микропроцессорами Xtensa 32-bit (под номерами 0 и 1), то есть они двухъядерные. При запуске кода из Arduino IDE, по умолчанию используется ядро 1. В данном уроке мы рассмотри, как запускать код на втором ядре параллельно с первым.
Для того, что бы увидеть на каком ядре мы работаем, есть функция: xPortGetCoreID() . Запустив данную функцию мы визуально увидим, на каком ядре мы работаем:

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());
delay(1000);
}

Запустив данный код мы увидим следующее:

Теперь мы с Вами создадим две задачи для разных ядер:

  • Для ядра 0 создадим Task1
  • Для ядра 1 создадим Task2

Так же надо учитывать, что система FreeRTOS уже добавлена в ESP32, — подключать библиотеку FreeRTOS не нужно.

TaskHandle_t Task1;
TaskHandle_t Task2;
 
// Определяем пины светодиодов
const int led1 = 2;
const int led2 = 4;
 
void setup() {
  Serial.begin(115200);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
}
 
  //создаем задачу, которая будет выполняться на ядре 0 с максимальным приоритетом (1)
  xTaskCreatePinnedToCore(
                    Task1code,  // Функция задачи. 
                    «Task1»,     //Имя. 
                    10000,       /* Размер стека функции */
                    NULL,        /* Параметры */
                    1,           /* Приоритет */
                    &Task1,      /* Дескриптор задачи для отслеживания */
                    0);          /* Указываем пин для данного ядра */                  
  delay(500);
 
  //Создаем задачу, которая будет выполняться на ядре 1 с наивысшим приоритетом (1)
  xTaskCreatePinnedToCore(
                    Task2code,   /* Функция задачи. */
                    «Task2»,     /* Имя задачи. */
                    10000,       /* Размер стека */
                    NULL,        /* Параметры задачи */
                    1,           /* Приоритет */
                    &Task2,      /* Дескриптор задачи для отслеживания */
                    1);          /* Указываем пин для этой задачи */
    delay(500);
}
 
//Task1code: мигает светодиодом раз в секунду
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: мигает светодиодом раз в 0,7 секунды
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() {
  
}
 
 

 

 

Запустив данный код на мониторе порта мы увидим, что теперь используем оба ядра, а не одно: