ESP32-雙核心

一、參考文件與紀錄

對於高中生的專題實作當中,如果不使用雙核心,那就等於跟使用Arduino一樣了

夜市小霸王在MAKERPRO寫了相關的說明,把相關的說明列在下面

資料來源:https://makerpro.cc/2020/03/use-esp32-dual-core-for-parallel-processing-to-improve-performance/

ESP32有著240/160MHz的雙核心CPU

從左圖架構就可以看出來ESP32晶片強大的部分,而且開發板一片才200元左右


為了測試指派任務給Core 0、Core 1,所以會使用到xTaskCreatePinnedToCore」函數


另外xPortGetCoreID()」函數列出目前用的core

夜市小霸王的這篇文章的圖很簡單的說明

  • 核心1專心處理感測器部分

  • 核心0只處理上傳

維持間20秒,如果是單核心,可能在執行完感測器元件偵測值後,上船會因為網路的不穩定因素多3-5秒,就不適程式當初所預期的20秒。

而且一直delay下去,時間就會一直拉長

程式碼從網站轉貼下來執行的

觀察到core 0都沒使用到

void setup() {

Serial.begin(115200);

}

void loop() {

Serial.println("HelloWorld!");

Serial.print("使用核心編號:");

Serial.println(xPortGetCoreID());//xPortGetCoreID()顯示執行核心編號

delay(1000);

}

小霸王實測比較差異-讀取資料上傳至ThingSpeak

把每次任務的時間做相減,會發現每一次的時間都變長

把把每次任務的時間做相減,會發現每一次的時間控制誤差在0.1秒

三、實際可執行的例子

  1. 先用TaskHandle_t 來宣告Task

  2. 然後再將Task指定運行的CPU Core!

TaskHandle_t task1; /* 任務控制代碼 也可以寫成TaskHandle_t task1,task2 */

TaskHandle_t task2;


void codeForTask1( void * parameter )

{

for(;;) { /*task必須無窮循環,不能自行中斷*/

delay(1000);

Serial.print("This Task1 run on Core: ");

Serial.println(xPortGetCoreID());

Serial.println("這是第一個task任務,指派給特定核心的任務:開工愉快");

delay(1000);

}

}


void codeForTask2( void * parameter )

{

for(;;) { /*task必須無窮循環,不能自行中斷*/

delay(1000);

Serial.print("This Task2 run on Core: ");

Serial.println(xPortGetCoreID());

Serial.println("這是第二個task任務,股票賺大錢");

delay(1000);

}

}



void setup() {

Serial.begin(115200);

/*程式載入後,先執行*/

xTaskCreatePinnedToCore(

codeForTask1, /*Task Function. */

"Task1", /*name of task. */

1000, /*Stack size of task. */

NULL, /* parameter of the task. */

1, /* proiority of the task. */

&task1, /* Task handel to keep tra ck of created task. */

0);

vTaskDelay(100);

xTaskCreatePinnedToCore(

codeForTask2, /*Task Function. */

"Task2", /*name of task. */

1000, /*Stack size of task. */

NULL, /* parameter of the task. */

1, /* proiority of the task. */

&task2, /* Task handel to keep tra ck of created task.就是前面宣告的第一二行,前面加& */

1);

vTaskDelay(100);


}



void loop() {

/*不斷的執行*/


}


其他

xTaskCreatePinnedToCore(

codeForTask2, /*Task Function. */

"Task2", /*name of task. */

10000, /*Stack size of task. */

NULL, /* parameter of the task. */

1, /* proiority of the task. */

&Task2, /* Task handel to keep tra ck of created task. */

1); /* choose Core */

最後一個變數如果改成tskNO_AFFINITY,則是讓RTOS去判斷最佳的執行核心