使用 ESP32 的 FreeRTOS 實現多任務


簡介

使用 ESP-IDF(Espressif IoT Development Framework)寫多任務程式,主要是利用 FreeRTOS 提供的多任務管理功能。ESP32 的多任務管理是基於 FreeRTOS 實現的,因此您可以利用 FreeRTOS 提供的 API 來創建和管理多個任務。

安裝 VSCode 和 ESP-IDF VSCode 擴展

確保你已經安裝和配置好了 ESP-IDF 開發環境。您也可以參考 ESP32 入門到精通 – 在 VSCode 安裝 ESP-IDF 插件 這篇文章。

ESP32 DevKit 開發模組

選擇一個 ESP32 模組如 ESP32 DevKitC V4

新建 ESP32 專案

利用在 VSCode 的 IDF 插件來新建一個 ESP32 專案可參考 ESP32 入門到精通 – 如何用 VSCode 創建 ESP32 專案

使用 xTaskCreate

利用 FreeRTOS 提供的函數用來創建一個新的任務。它的參數包括任務函數指針、任務名稱、任務堆棧大小、任務參數、任務優先級和任務句柄。

編寫代碼

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "time.h"

// Define log tags for tasks
static const char *TAG1 = "Task1";
static const char *TAG2 = "Task2";

// Get current time
const char* get_time_string() {
    static char time_str[64];
    time_t now;
    struct tm timeinfo;
    time(&now);
    localtime_r(&now, &timeinfo);
    strftime(time_str, sizeof(time_str), "%H:%M:%S", &timeinfo);
    return time_str;
}

void task1(void *parameter)
{
    while (1)
    {
        ESP_LOGI(TAG1, "[%s] Task 1 is running", get_time_string());
        vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay for 1000 ms
    }
}

void task2(void *parameter)
{
    while (1)
    {
        ESP_LOGI(TAG2, "[%s] Task 2 is running", get_time_string());
        vTaskDelay(2000 / portTICK_PERIOD_MS); // Delay for 2000 ms
    }
}

void app_main()
{
    // Create the task-1
    xTaskCreate(&task1, "Task 1", 2048, NULL, 1, NULL);
    
    // Create the task-2
    xTaskCreate(&task2, "Task 2", 2048, NULL, 1, NULL);
}

編譯和燒錄

在 VSCode 中找到 "ESP32-IDF : Build, Flash and Monitor" ICON 執行和燒錄。

查看結果

使用 esp_log 在 ESP32 上執行,則在串口監控器中顯示以下日誌輸出如下所示...
I (1314) Task1: [00:00:01] Task 1 is running
I (2314) Task2: [00:00:02] Task 2 is running
I (2314) Task1: [00:00:02] Task 1 is running
I (3314) Task1: [00:00:03] Task 1 is running
I (4314) Task2: [00:00:04] Task 2 is running
I (4314) Task1: [00:00:04] Task 1 is running
I (5314) Task1: [00:00:05] Task 1 is running
I (6314) Task2: [00:00:06] Task 2 is running
I (6314) Task1: [00:00:06] Task 1 is running
I (7314) Task1: [00:00:07] Task 1 is running
I (8314) Task2: [00:00:08] Task 2 is running
I (8314) Task1: [00:00:08] Task 1 is running
I (9314) Task1: [00:00:09] Task 1 is running
在 FreeRTOS 系統中,task1 和 task2 是異步運行的,這表示著它們的執行並不會同步進行。這是因為 FreeRTOS 使用時間片輪轉調度(Round-Robin Scheduling)或者其他調度策略來管理任務的運行且由以上的日誌的輸出可以出異步運行。

結論

通過以上步驟和方法,就能夠使用 VSCode 來開發 ESP32 的應用程式,並且以 FreeRTOS 實現多任務。如果有任何錯誤,請檢查 ESP-IDF 和 VSCode 等的配置,確保路徑和環境變量都設置正確。