HW 프로그래밍/아두이노

ESP32의 Dual Core를 활용하자.

N2info 2021. 2. 2. 20:07

1. ESP32와 ESP8266의 차이는?

 ESP32는 ESP8266과 많은 차이를 보인다.  그중 가장 으뜸을 꼽으라 하면 듀얼코어와 싱글코어의 차이라고 하겠다.  ESP32는 듀얼코어이다. !!

2. 음 듀얼코어라고? 난 안쓰는데?

 사실 이미 쓰고 있다. 느끼지 못할 뿐이다.  Arduino IDE로 프로그램을 만들어서 실행중이라면 이미 2개의 코어를 모두 쓰고 있다. 다만 모르고 있을 뿐이다.
일반적으로
  Core 0 : 무선 통신과 같은  ESP32 본연의 기능이 실행됨
  Core 1 : 컴파일된 Arduino 코드가 실행됨

3. 알아서 듀얼 코어를 잘 사용하는데 왜?

 사실 간단하게 온도나 측정하거나 LED나 껏다가 켜는 등의 별거 아닌것들을 하는 경우 큰 의미가 없다. 온도나 측정하는데 ESP32는 오버 스펙이다.  각설하고, ESP32의 코어 하나로 수행하기에 벅찬 작업을 하는 듀얼 코어를 사용한다.  ESP32의 Core 0은 무선 통신과 같은 작업을 수행하기에 상대적으로 널널하다. 즉 대부분 쉬고 있다. 이를 활용하면 ESP32의 기능을 극대화 할 수 있다.  또는 Core 0을 이용하여 Core 1의 패닉 상태를 조사하고, 필요시 리부팅을 할 수 있다.

4. 사용 예제는?

크게 어렵지 않은 예제 코드를 아래에 기록해 본다.  예제는 코어 2개에서 각각의 analogRead를 수행하는 예제이다.

/* -----------------------------------------------

   ESP32 Dual Core tester

  ----------------------------------------------- */

 

//-----------------------------------------------

// global functions

//-----------------------------------------------

void Task1(void * parameter)

{

  while (true) {

    unsigned long start = micros();

    // very long task..

    for ( uint32_t i = 0; i < 1000; i++) {

      analogRead(33);

    }

    Serial.printf("Task 1 done  (on Core : %d)  Elps = %d  µs \n", xPortGetCoreID(), micros() - start);

    delay(100);

  }

}

void Task2(void * parameter)

{

  while (true) {

    unsigned long start = micros();

    // very long task..

    for ( uint32_t i = 0; i < 1000; i++) {

      analogRead(35);

    }

    //workLoad();

    Serial.printf("Task 2 done  (on Core : %d)  Elps = %d  µs \n", xPortGetCoreID(), micros() - start);

    delay(100);

  }

}

TaskHandle_t TaskA, TaskB;

 

//-----------------------------------------------

// setup functions

//-----------------------------------------------

void setup() {

  Serial.begin(115200);

  delay(100);

 

  xTaskCreatePinnedToCore(

    Task1,                  /* pvTaskCode */

    "Workload1",            /* pcName */

    1000,                   /* usStackDepth */

    NULL,                   /* pvParameters */

    1,                      /* uxPriority */

    &TaskA,                 /* pxCreatedTask */

    0);                     /* xCoreID */

 

  xTaskCreatePinnedToCore(

    Task2,

    "Workload2",

    1000,

    NULL,

    1,

    &TaskB,

    1);

}

 

//-----------------------------------------------

// loop functions

//-----------------------------------------------

void loop() {

  // This task will run in the core 1

  unsigned long start = micros();

  for ( uint32_t i = 0; i < 1000; i++) {

    // do nothing

  }

  Serial.printf("Task 0 done  (on Core : %d)  Elps = %d  µs \n", xPortGetCoreID(), micros() - start);

  delay(10) ;

}

 

 

 

위의 예제를 실행 시키면 아래와 같은 출력을 볼 수 있다.

 

Task 0 done  (on Core : 1)  Elps = 0  µs 

Task 0 done  (on Core : 1)  Elps = 2  µs 

Task 1 done  (on Core : 0)  Elps = 12450  µs 

Task 2 done  (on Core : 1)  Elps = 12380  µs 

Task 0 done  (on Core : 1)  Elps = 0  µs 

Task 0 done  (on Core : 1)  Elps = 0  µs 

Task 0 done  (on Core : 1)  Elps = 0  µs 

Task 0 done  (on Core : 1)  Elps = 0  µs 

 

Task 0 done  (on Core : 1)  Elps = 0  µs 

 

 

andy-power.blogspot.com/2018/12/esp32-dual-core.html

 

ESP32의 Dual Core를 활용하자.

ESP, ESP8266, ESP32등과 IoT를 결합하는 기술을 다루는 블로그입니다.

andy-power.blogspot.com