ESP模塊因其Wi-Fi功能(如ESP8266、ESP-12E等)而廣受歡迎。這些都是具有Wi-Fi功能的強大微控制器模塊。還有一個ESP模塊,它比以前的ESP模塊更強大,更通用 - 其名稱為ESP32。它具有藍牙和Wi-Fi連接,并在許多物聯網項目中使用了ESP32。但是很少有人知道ESP32是雙核微控制器。
ESP32具有兩個32位TensilicaXtensa LX6微處理器,這使其成為功能強大的雙核(core0和core1)微控制器。有單核和雙核兩種版本。但是雙核版本更受歡迎,因為它們之間沒有明顯的價格差異。
可以使用Arduino IDE、Espressif IDF、Lua RTOS等對ESP32進行編程。使用Arduino IDE進行編程時,由于Core0已編程用于RF通信,因此代碼僅在Core1上運行。但是在本篇文章中,我們將展示如何使用ESP32的兩個內核同時執行兩項操作。在這里,第一個任務是使板載LED閃爍,第二個任務是從DHT11傳感器獲取溫度數據。
首先讓我們看看多核處理器比單核的優勢。
多核處理器的優勢
1.當有兩個以上的進程要同時工作時,多核處理器很有用。
2.由于工作分布在不同的內核之間,因此速度提高了,并且可以同時完成多個過程。
3.可以降低功耗,因為當任意內核處于空閑模式時,它可以用來關閉當時不使用的外圍設備。
4.與單核處理器相比,雙核處理器在不同線程之間切換的頻率更低,因為它們可以一次處理兩個,而不是一次處理一個線程。
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() function running on core: ");
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 setup函數中創建任務。在這里,我們將創建兩個任務,一個任務是每0.5秒閃爍一次LED,另一任務是每2秒獲得溫度讀數。
xTaskCreatePinnedToCore()函數使用7個參數:
● 實現任務的函數名稱(task1)
● 任務的任何名稱(“ task1”等)
● 分配給任務的堆棧大小,以字為單位
● 任務輸入參數(可以為NULL)
● 任務的優先級(0是最低優先級)
● 任務句柄(可以為NULL)
● 任務將運行的內核ID(0或1)
現在,通過在xTaskCreatePinnedToCore()函數中提供所有參數來創建Task1,以使指示燈閃爍。
xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, NULL,0);
同樣,為任務2創建Task2,并在第7個參數中將內核ID設置為1。
xTaskCreatePinnedToCore(Task2code, "Task2", 10000, NULL, 1, NULL,1);
您可以根據任務的復雜性更改優先級和堆棧大小。
2.現在,我們將實現Task1code和Task2code函數。這些函數包含所需任務的代碼。在本例中,第一個任務將使LED閃爍,另一個任務將獲取溫度。因此,在void setup函數之外,為每個任務創建兩個單獨的函數。
Task1code函數實現了0.5秒后板上LED閃爍,如下所示:
Void Task1code( void * parameter) {
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for(;;) {//infinite loop
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
??delay(500);
}
}
同樣,實現Task2code函數以獲取溫度。
void Task2code( void * pvParameters ){
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
for(;;){
float t = dht.readTemperature();
Serial.print("Temperature: ");
Serial.print(t);
delay(2000);
}
}
3.此處的void loop函數將保持為空。 我們已經知道loop和setup函數在core1上運行,因此您也可以在void loop函數中實現core1任務。
現在代碼部分已經結束,因此只需在“Tool”菜單中選擇ESP32板,即可使用Arduino IDE上傳代碼。 確保已將DHT11傳感器連接到ESP32的D13引腳。
現在,可以在串口監視器上監視結果,如下所示:
可以通過使用ESP32的雙核同時運行多個任務來構建諸如實時系統之類的復雜應用程序。
編輯:hfy
-
微控制器
+關注
關注
48文章
7496瀏覽量
151083
發布評論請先 登錄
相關推薦
評論