TOOLS GAMES DEVLOG DOCS ABOUT CONTACT
HOME > DOCS > Embedded / IoT > ESP32 FreeRTOS 듀얼 코어 분산 태스크 및 스레드 세이프 큐(Queue) 통신
Embedded / IoT Intermediate ESP-IDF / Arduino ESP32 Core

ESP32 FreeRTOS 듀얼 코어 분산 태스크 및 스레드 세이프 큐(Queue) 통신

Core 0(Wi-Fi/센서 수집)과 Core 1(UI 렌더링/모터 제어)에 독립 태스크를 고정(PinToCore)하고 FreeRTOS Queue를 통해 락 없이 데이터를 교환하는 패턴.

#Embedded #ESP32 #FreeRTOS #DualCore #Multithreading
핵심 개념ESP32는 2개의 Xtensa 32비트 LX6 코어를 탑재하고 있습니다. 단일 루프에서 Wi-Fi 패킷 통신과 고속 센서 읽기, 디스플레이 화면 갱신을 동시에 돌리면 프레임 드랍이 발생합니다. Core 0에 통신 태스크를, Core 1에 렌더링 태스크를 할당하고 Queue로 결합합니다.

1. FreeRTOS 듀얼코어 태스크 스케줄링 C++ 코드

dual_core_tasks.ino
#include <Arduino.h>

struct SensorData {
    int id;
    float value;
};

QueueHandle_t dataQueue;

void SensorTask(void *pvParameters) {
    SensorData data;
    while (1) {
        data.id = 1;
        data.value = analogRead(34) * (3.3f / 4095.0f);
        // 큐에 데이터 전송 (대기시간 10ms)
        xQueueSend(dataQueue, &data, pdMS_TO_TICKS(10));
        vTaskDelay(pdMS_TO_TICKS(50)); // 20Hz 수집 주기
    }
}

void DisplayTask(void *pvParameters) {
    SensorData receivedData;
    while (1) {
        if (xQueueReceive(dataQueue, &receivedData, portMAX_DELAY)) {
            Serial.printf("[Core %d] Sensor %d: %.2f V\n", 
                          xPortGetCoreID(), receivedData.id, receivedData.value);
        }
    }
}

void setup() {
    Serial.begin(115200);
    dataQueue = xQueueCreate(10, sizeof(SensorData));

    // Core 0에 센서 수집 태스크 고정
    xTaskCreatePinnedToCore(SensorTask, "SensorTask", 4096, NULL, 1, NULL, 0);
    // Core 1에 디스플레이/로직 태스크 고정
    xTaskCreatePinnedToCore(DisplayTask, "DisplayTask", 4096, NULL, 1, NULL, 1);
}

void loop() {
    vTaskDelete(NULL); // 기본 loop 태스크 제거
}

참고자료 & 관련 링크