デュアルコア ESP32 を有効にして、デュアルコア機能が複数のタスクを同時に実行できるようにする方法
導入
ESP32-WROOM-32 モジュールには、低電力 Xtensa® 32 ビット LX6 MCU が 2 つ内蔵されており、2 つの CPU コア (コア 0 とコア 1) を独立して制御できます。複数のコードを両方のコアで同時に実行できるため、ESP32 はマルチタスク (特定の処理を実行するコード) が可能になります。Arduino IDE はデフォルトでコア 1 を有効にします。ESP32 は、リアルタイム オペレーティング システム RTOS を実行し、複数の独立して実行されるタスクを並行して処理できます。コードの特定の部分を特定のコアに割り当てるには、タスクを作成する必要があります。タスクを作成するときに、タスクを実行するコアとその優先順位を選択できます。優先順位の値は 0 から始まり、0 が最も低い優先順位になります。プロセッサは優先度の高いタスクを最初に実行します。
ESP32 のどのコアが現在タスクを実行しているかを確認する
Arduino IDE を開き、次のコードを ESP32 にアップロードし、
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());
}
シリアル モニターを開いて、ESP32 の現在のコア 1 がタスクを実行していることを確認します。
デュアルコアがタスクを同時に実行
Arduino IDE を開き、次のコードを ESP32 にアップロードします。
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() {
}
このコードはコア 0 で実行されて LED1 が 1000 ミリ秒ごとに点滅し、コア 1 で実行されて LED2 が 700 ミリ秒ごとに点滅します。両方のタスクの優先順位は 1 で、同時に実行され、カーネル情報がシリアル モニターに出力されます。デュアルコア実行が有効になっておらず、デフォルトのシングルコア シーケンスが使用されている場合、LED1 と LED2 を異なる間隔で同時に点滅させることはできません。
タスクの実行中にタスクを削除したい場合は、関数 vTaskDelete(Task1) を呼び出すことができます。
要約する
デュアルコア機能を備えたESP32により、プログラムを簡素化し、並列機能を備えたアプリケーションを設計する際の効率が向上します。たとえば、1 つのコアを使用してセンサーの読み取り値を取得し、別のコアを使用して読み取り値に基づいて他のタスクを実行します。