Để nắm rõ được cách sử dụng ESP32 Dual Core trên Arduino IDE, trước tiên chúng ta cùng nhau tìm hiểu xem dual core mang lại cho chúng ta lợi ích gì.
Bạn nên đọc:
- Cài đặt thư viện ESP32 trên Arduino IDE
- Lấy thời gian từ Internet sử dụng ESP32
- Sử dụng Bluetooth (BLE) của ESP32 trên Arduino
CPU Dual Core là gì?
Chúng ta đều biết mỗi vi xử lý đều phải có một CPU (core) để làm nhiệm vụ là trung tâm xử lý mọi hoạt động. Giống như khi bạn vận hành một nhà máy, khi nhà máy bạn còn nhỏ thì bạn chỉ cần dùng 1 máy và 1 người là đủ nhưng khi bạn có nhiều đơn hàng thì bắt buộc bạn phải mở rộng thêm máy thêm người. Vi xử lý cũng vậy, khi bạn muốn ứng dụng của mình chạy được nhiều tác vụ hơn, xử lý các tác vụ đó nhanh hơn thì bạn cần thêm core để đảm nhiệm các nhiệm vụ khác nhau.
Cấu tạo Dual Core trên ESP32
CPU: Xtensa Dual-Core 32-bit LX6 microprocessor
Ngoài việc đầy đủ các chuẩn giao tiếp, wifi, bluetooth thì ESP32 đặc biệt có dual core. Giúp khả năng thực thi các tác vụ trở nên nhanh và nhiều hơn, phù hợp cho các ứng dụng yêu cầu phức tạp và ổn định.
Cách sử dụng Dual Core trên ESP32
Để sử dụng được dual core trên ESP32 chúng ta buộc phải lập trình cấu hình cho nó chạy theo từng core riêng biệt.
Trên ESP32 có 2 core:
- CORE 0
- CORE 1
Để thử nghiệm việc chạy dual core trong bài viết, mình sẽ sử dụng Arduino IDE. Có thể sử dụng ESP-IDF nữa nhé (sẽ update sau).
Kiểm tra code đang chạy trên core nào
Đặc biệt nếu như không cấu hình thì mặc định toàn bộ code hay các tác vụ xử lý sẽ được chạy trên core 1 của ESP32. Mình sẽ thử kiểm tra xem đúng không nhé: Sử dụng hàm
xPortGetCoreID()
Code trên Arduino Sketch, các bạn copy vào bật Serial lên xem nhé
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()); }
Kết quả in ra:
Hệ điều hành FreeRTOS hỗ trợ chạy dual core trên ESP32
Arduino IDE hỗ trợ FreeRTOS cho ESP32, đây là hệ điều hành thời gian thực. Điều này cho phép xử lý một số tác vụ song song chạy độc lập.
Tác vụ có thể là đoạn mã thực thi một cái gì đó. Ví dụ, nhấp nháy đèn LED, kết nối wifi, bluetooth, đọc cảm biến, gửi giá trị cảm biến, v.v.
Để gán các đoạn code cho từng core thì trước tiên cần tạo một tác vụ. Khi tạo một tác vụ bạn có thể chọn nó sẽ chạy trong lõi (core) nào, cũng như mức độ ưu tiên của nó. Giá trị ưu tiên bắt đầu từ 0, trong đó 0 là mức ưu tiên thấp nhất. Bộ xử lý sẽ chạy các tác vụ với mức độ ưu tiên cao đến thấp.
Tiến hành chạy thử nghiệm Dual Core trên ESP32 sử dụng Arduino IDE
Mình sẽ tiến hành thử nghiệm sử dụng ESP32 để chạy Dual Core xử lý Blink led trên 2 core 0 và 1
- Tạo một tác vụ: Khai báo sử dụng trên 2 core
TaskHandle_t Task1; TaskHandle_t Task2;
- Gọi hàm xử lý trên từng core
xTaskCreatePinnedToCore(...)
Bên trong (…) là các đối số cần cấu hình theo hàm.
xTaskCreatePinnedToCore( Task1code, /* Tên hàm sẽ xử lý trên core được chọn */ "Task1", /* Tên của tác vụ */ 10000, /* Kích thướt của tác vụ */ NULL, /* Đối số đầu vào bạn muốn đưa vào bên trong hàm xử lý ở trên */ 0, /* Mức độ ưu tiên xử lý (0 là thấp nhất) */ &Task1, /* Tác vụ bạn khai báo ở phía trên */ 0); /* Chọn core bạn muốn chạy tác vụ (0 hoặc 1) */
- Tiếp theo viết 1 hàm xử lý các công việc bạn muốn (Task1code)
Void Task1code( void * parameter) { for(;;) { //Xử lý blink led hoặc bất cứ gì bạn muốn //parameter chính là đối số truyền vào từ cấu hình core } }
Vòng lặp for(;;) cho phép lặp lại tác vụ bạn muốn xử lý
Trong khi chạy vòng lặp for(;;), nếu muốn dừng tác vụ thì bạn có thể gọi hàm
vTaskDelete(...)
Với bên trong dấu () là tên tác vụ mà bạn đặt lúc cấu hình ở đây chính là: “Task1”. Trên đây là toàn bộ các bước cấu hình để chạy trên 1 core của ESP32 (core 0), tương tự như vậy các bạn cấu hình cho core 1.
Code hoàn chỉnh thử nghiệm blink led trên 2 core
Các bạn cần chuẩn bị như hình dưới:
- Đặc biệt các bạn cần cài đặt môi trường để chạy ESP32 trên Arduino IDE nhé, nếu chưa cài đặt các bạn hãy làm theo hướng dẫn ở link phía đầu trang. Và cần cài đặt thêm hệ điều hành FreeRTOS trong Arduino nữa.Ở giao diện chính của Aruduino IDE, Sketch > Include Library > Manage Libraries. Search từ khóa FreeRTOS và cài đặt thư viện
Tiến hành chèn code sau vào Arduino Sketch nhé:
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() { }
Sau đó bật Serial lên quan sát thành quả:
Hình ảnh chạy thực tế:
Trên đây mình đã giới thiệu sơ lược về Dual Core trên ESP32 và có hướng dẫn chi tiết cách sử dụng dual core trên ESP32. Có bất kỳ thắc mắc gì xin để lại câu hỏi dưới mục bình luận.
Chúc các bạn thành công!
Sao em chạy nó toàn bị hard reset admin nhỉ
Cảm ơn anh vì đã chia sẻ một bài viết dễ hiểu.