ESP 모듈은 ESP8266, ESP-12E 등과 같은 Wi-Fi 기능으로 유명합니다. 이들은 모두 Wi-Fi 기능을 갖춘 강력한 마이크로 컨트롤러 모듈입니다. 이전 ESP 모듈보다 더 강력하고 다재다능한 ESP 모듈이 하나 더 있습니다. 이름은 ESP32 입니다. Bluetooth 및 Wi-Fi 연결이 있으며 이미 ESP32의 BLE 기능을 설명하고 많은 IoT 프로젝트에서 ESP32를 사용했습니다. 그러나 ESP32가 듀얼 코어 마이크로 컨트롤러 라는 사실을 아는 사람은 거의 없습니다.
ESP32 에는 2 개의 32 비트 Tensilica Xtensa LX6 마이크로 프로세서가있어 강력한 듀얼 코어 (core0 및 core1) 마이크로 컨트롤러가됩니다. 단일 코어 및 듀얼 코어의 두 가지 변형으로 제공됩니다. 그러나 듀얼 코어 변형은 큰 가격 차이가 없기 때문에 더 많이 사용됩니다.
ESP32는 Arduino IDE, Espressif IDF, Lua RTOS 등을 사용하여 프로그래밍 할 수 있습니다. Arduino IDE로 프로그래밍하는 동안 Core0은 이미 RF 통신용으로 프로그래밍되어 있으므로 코드는 Core1에서만 실행됩니다. 그러나 여기이 튜토리얼 은 ESP32의 두 코어를 사용 하여 두 작업을 동시에 수행 하는 방법을 보여 줍니다. 여기서 첫 번째 작업은 온보드 LED를 깜박이는 것이고 두 번째 작업은 DHT11 센서에서 온도 데이터를 가져 오는 것입니다.
먼저 단일 코어에 비해 멀티 코어 프로세서의 장점을 살펴 보겠습니다.
멀티 코어 프로세서의 장점
- 멀티 코어 프로세서는 동시에 작업 할 프로세스가 2 개 이상일 때 유용합니다.
- 작업이 서로 다른 코어에 분산됨에 따라 작업 속도가 빨라지고 여러 프로세스를 동시에 완료 할 수 있습니다.
- 코어가 유휴 모드에있을 때 사용하지 않는 주변 장치를 종료하는 데 사용할 수 있기 때문에 전력 소비를 줄일 수 있습니다.
- 듀얼 코어 프로세서는 한 번에 하나씩 처리하는 대신 한 번에 두 개를 처리 할 수 있기 때문에 싱글 코어 프로세서보다 다른 스레드간에 전환하는 빈도가 적습니다.
ESP32 및 FreeRTOS
ESP32 보드에는 이미 FreeRTOS 펌웨어가 설치되어 있습니다. FreeRTOS는 멀티 태스킹에 매우 유용한 오픈 소스 실시간 운영 체제입니다. RTOS는 리소스를 관리하고 시스템 성능을 최대화하는 데 도움이됩니다. FreeRTOS에는 다양한 목적을위한 많은 API 기능이 있으며 이러한 API를 사용하여 작업을 생성하고 다른 코어에서 실행할 수 있습니다.
FreeRTOS API에 대한 전체 설명서는 여기에서 찾을 수 있습니다. 코드에서 일부 API를 사용하여 두 코어 모두에서 실행되는 멀티 태스킹 애플리케이션을 구축하려고합니다.
ESP32 코어 ID 찾기
여기서는 Arduino IDE를 사용하여 코드를 ESP32에 업로드합니다. 코드가 실행되는 Core ID를 알기 위해 API 함수가 있습니다.
xPortGetCoreID ()
이 함수는 void setup () 및 void loop () 함수에서 호출하여 이러한 함수가 실행되는 코어 ID를 알 수 있습니다.
아래 스케치를 업로드하여이 API를 테스트 할 수 있습니다.
void setup () { Serial.begin (115200); 코어에서 실행되는 Serial.print ("setup () 함수:"); Serial.println (xPortGetCoreID ()); } void loop () { Serial.print ("loop () function running on core:"); Serial.println (xPortGetCoreID ()); }
위의 스케치를 업로드 한 후 직렬 모니터를 열면 아래와 같이 두 기능이 core1에서 실행되고 있음을 알 수 있습니다.
위의 관찰을 통해 기본 Arduino 스케치가 항상 core1에서 실행 된다는 결론을 내릴 수 있습니다.
ESP32 듀얼 코어 프로그래밍
Arduino IDE는 ESP32 용 FreeRTOS를 지원하며 FreeRTOS API를 사용하면 두 코어에서 독립적으로 실행할 수있는 작업을 생성 할 수 있습니다. 작업은 LED 깜박임, 온도 전송 등과 같은 보드에서 일부 작업을 수행하는 코드 조각입니다.
아래 함수는 두 코어 모두에서 실행할 수있는 작업을 만드는 데 사용됩니다. 이 함수에서 우선 순위, 코어 ID 등과 같은 인수를 제공해야합니다.
이제 아래 단계에 따라 작업 및 작업 기능을 만듭니다.
1. 먼저 void 설정 기능 에서 작업을 생성합니다. 여기서는 0.5 초마다 LED를 깜박이는 작업과 2 초마다 온도 판독 값을 얻는 작업의 두 가지 작업을 만듭니다.
xTaskCreatePinnedToCore () 함수는 7 개의 인수를 사용합니다.
- 작업을 구현하기위한 함수 이름 (task1)
- 작업에 지정된 모든 이름 ("task1"등)
- 태스크에 할당 된 스택 크기 (1 워드 = 2 바이트)
- 태스크 입력 매개 변수 (NULL 일 수 있음)
- 작업의 우선 순위 (0이 가장 낮은 우선 순위)
- 작업 핸들 (NULL 일 수 있음)
- 작업이 실행될 코어 ID (0 또는 1)
이제 xTaskCreatePinnedToCore () 함수에 모든 인수를 제공 하여 LED를 깜박이는 Task1을 만듭니다.
xTaskCreatePinnedToCore (Task1code, "Task1", 10000, NULL, 1, NULL, 0);
마찬가지로 Task2에 대해 Task2를 만들고 7 번째 인수 에서 코어 ID 1을 만듭니다.
xTaskCreatePinnedToCore (Task2code, "Task2", 10000, NULL, 1, NULL, 1);
작업의 복잡성에 따라 우선 순위와 스택 크기를 변경할 수 있습니다.
2. 이제 Task1code 와 Task2code 함수를 구현 하겠습니다 . 이러한 함수에는 필요한 작업에 대한 코드가 포함되어 있습니다. 우리의 경우 첫 번째 작업은 LED를 깜박이고 다른 작업은 온도를 가져옵니다. 따라서 void 설정 기능 외부에서 각 작업에 대해 두 개의 별도 기능을 만드십시오.
0.5 초 후 온보드 LED가 깜박이는 Task1code 기능 은 아래와 같이 구현됩니다.
Void Task1code (void * parameter) {Serial.print ( "Task1 running on core"); Serial.println (xPortGetCoreID ()); for (;;) {// 무한 루프 digitalWrite (led, HIGH); 지연 (500); digitalWrite (LED, LOW), 지연 (500); } }
마찬가지로 온도를 가져 오는 Task2code 함수를 구현 합니다.
void Task2code (void * pvParameters) {Serial.print ("Task2 running on core"); Serial.println (xPortGetCoreID ()); for (;;) { float t = dht.readTemperature (); Serial.print ("온도:"); Serial.print (t); 지연 (2000); } }
3. 여기서 void 루프 함수는 비어 있습니다. 루프 및 설정 기능이 core1에서 실행 된다는 것을 이미 알고 있듯이 void 루프 기능에서도 core1 작업을 구현할 수 있습니다.
이제 코딩 부분이 끝났으므로 Tools 메뉴에서 ESP32 보드를 선택하여 Arduino IDE를 사용하여 코드를 업로드하십시오. DHT11 센서를 ESP32의 D13 핀에 연결했는지 확인하십시오.
이제 결과는 아래와 같이 직렬 모니터 또는 Arduino IDE에서 모니터링 할 수 있습니다.
ESP32의 듀얼 코어를 사용하여 여러 작업을 동시에 실행하여 실시간 시스템과 같은 복잡한 애플리케이션을 구축 할 수 있습니다.
데모 비디오와 함께 완전한 코드가 아래에 제공됩니다.