2

Cách sử dụng ESP32 Dual Core trên Arduino IDE

dual-core-esp32

Để 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:

CPU Dual Core là gì?

CPU (core) của một vi xử lý

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

Kiến trúc phần cứng của ESP32

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.

Cấu tạo core trên ESP32

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:

Test code chạy trên core nào

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:

Sơ đồ nối led để blink

  • Đặ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

Thêm thư hệ điều hành FreeRTOS trên ESP32

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ả:

Serial blink led esp32 dual core

Hình ảnh chạy thực tế:

Demo blink led ESP32 Dual Core

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!

2 Bình luận

Trả lời

Email của bạn sẽ không được hiển thị công khai.