ESP32 FreeRTOS 튜토리얼 가이드 6부작 6
FreeRTOS를 사용하여 ESP32에서 실시간 애플리케이션을 구축하는 방법을 배워보세요. 태스크 생성, 우선순위 처리, 메모리 관리, 태스크 간 통신에 관한 실용적인 튜토리얼을 살펴보세요. 각 예제는 실제 하드웨어에서 테스트되어 멀티태스킹을 숙달하고 ESP32의 듀얼 코어 성능을 최대한 활용할 수 있도록 도와줍니다.
ESP32 FreeRTOS(1부): FreeRTOS 및 작업 관리 소개
ESP32 FreeRTOS(2부): 스케줄러 및 작업 관리 이해
ESP32 FreeRTOS(3부): 작업 우선순위 및 스택 관리 설명
ESP32 FreeRTOS(4부): 작업 간 통신 설명 | 큐, 세마포어 및 이벤트 그룹
ESP32 FreeRTOS(5부): 소프트웨어 타이머 및 작업 알림 설명
ESP32 FreeRTOS(6부): ESP-IDF에서 작업을 일시 중지, 재개 및 삭제하는 방법
ESP32에서 FreeRTOS 작업 제어: 작업 일시 중지, 재개 및 삭제
작업 제어는 FreeRTOS의 가장 강력한 기능 중 하나입니다. 런타임에 작업을 일시 중지, 재시작 또는 완전히 삭제할 수 있습니다 . 이를 통해 ESP32 프로젝트를 더욱 유연하고 효율적으로 만들 수 있습니다. 작업을 올바르게 제어하는 방법을 알면 CPU 시간 낭비를 방지하고 메모리 사용량을 줄이며 시스템을 안정적으로 유지할 수 있습니다.
이 튜토리얼에서는 ESP-IDF에서 vTaskSuspend() , vTaskResume() , vTaskDelete()를 사용하는 방법을 알아봅니다 . 이 세 가지 API는 작업 수명 주기를 깔끔하고 예측 가능한 방식으로 관리하는 데 도움이 됩니다. 또한 실제 ESP32 애플리케이션에서 사용할 수 있는 실용적인 예제도 살펴봅니다.
이 FreeRTOS ESP32 시리즈 의 이전 부분, 특히 작업 스케줄링 , 작업 우선순위 , 작업 간 통신 에 대한 튜토리얼을 이미 따라오셨다면 이 가이드를 매우 쉽게 따라하실 수 있을 것입니다. 각 개념은 작업 관리의 큰 그림과 잘 어우러집니다.

ESP32에서 FreeRTOS 작업 제어: 작업 일시 중지, 재개 및 삭제
목차
- FreeRTOS의 작업 제어란 무엇인가요?
- vTaskSuspend() 및 vTaskResume()을 사용하여 작업 제어
- vTaskDelete()를 사용하여 작업 삭제
- 일시 중지, 재개, 삭제 및 알림 중에서 선택
- ESP32 FreeRTOS에서 작업 제어를 위한 모범 사례
- 결론
FreeRTOS의 작업 제어란 무엇인가요?
작업 제어는 런타임에 작업을 일시 중지 , 재개 또는 제거하는 기능을 의미합니다 . FreeRTOS는 이를 위한 간단한 API를 제공하며, ESP-IDF는 듀얼 코어 스케줄러를 통해 안정성을 더욱 높여줍니다. 적절한 작업 제어를 통해 ESP32 프로젝트의 예측 가능성과 효율성이 향상됩니다. 어떤 작업을 실행하고, 어떤 작업을 대기하고, 어떤 작업을 영구적으로 중지할지 사용자가 직접 결정할 수 있습니다. 이는 작업이 항상 연속적으로 실행될 필요가 없는 실제 애플리케이션에서 유용합니다.
FreeRTOS는 작업 제어를 위한 세 가지 주요 기능을 제공합니다.
- vTaskSuspend() : 작업 일시 중지
- vTaskResume() : 일시 중지된 작업을 다시 시작합니다.
- vTaskDelete() : 작업을 영구적으로 제거합니다.
이러한 API를 사용하면 ESP32를 다시 시작하지 않고도 시스템의 런타임 동작을 조정할 수 있습니다.
ESP32 프로젝트에서 작업 제어가 필요한 이유
ESP32 프로젝트는 종종 여러 작업을 동시에 실행합니다. 어떤 작업은 센서 데이터를 수집하고, 어떤 작업은 Wi-Fi 관리, 사용자 입력 처리, 또는 하드웨어 제어를 담당합니다. 모든 작업이 연속적으로 실행될 필요는 없습니다. 어떤 작업은 외부 이벤트가 발생할 때까지 기다려야 할 수도 있고, 어떤 작업은 작업 완료 후 중지되어야 할 수도 있습니다.
작업 제어는 다음과 같은 데 도움이 됩니다.
- 실행할 필요 없는 작업을 일시 중지하여 CPU 시간을 절약하세요 .
- 배터리를 사용하는 경우 전력 소비를 줄이는 것이 중요합니다.
- 작업이 완료된 작업을 삭제하여 메모리를 확보하세요 .
- 필요할 때만 작업을 재개하여 대응성을 향상시킵니다 .
적절한 작업 제어를 통해 ESP32는 더욱 지능적으로 동작합니다. 작업은 시스템에 실제로 필요할 때만 실행됩니다.
작업 상태가 작업 제어에 미치는 영향
작업 제어를 올바르게 사용하려면 FreeRTOS가 작업 상태를 처리하는 방식을 알아야 합니다 . 이전 작업 스케줄러 튜토리얼에서는 작업이 실행 중, 준비, 차단, 일시 중단 등 다양한 상태에 있을 수 있음을 살펴보았습니다.
작업 제어는 주로 다음 사이에서 작업을 전환합니다.
- 준비 완료에서 일시 중단 (vTaskSuspend를 호출할 때)
- 일시 중지에서 준비로 전환 (vTaskResume을 호출할 때)
- 삭제될 모든 상태 (vTaskDelete를 호출할 때)
일시 중단된 작업은 CPU 시간을 소모하지 않습니다. 스케줄링 과정에서 고려되지 않습니다. 스케줄러는 사용자가 작업을 재개할 때까지 해당 작업을 무시합니다. 삭제된 작업은 완전히 제거되고, 해당 작업의 스택 메모리는 해제됩니다.
작업 상태를 이해하면 작업을 일시 중단하거나 삭제할 때 시스템이 어떻게 동작하는지 예측할 수 있습니다. 이를 통해 버그나 스케줄러 오류를 방지할 수 있습니다.
작업을 일시 중단하거나 삭제하는 것이 합리적인 경우
모든 상황에서 작업을 일시 중단하거나 삭제할 필요는 없습니다. 하지만 많은 경우 작업을 일시 중단하거나 삭제하면 더 깔끔하고 가벼운 코드를 만들 수 있습니다.
다음과 같은 경우 작업을 일시 중단 해야 합니다 .
- 오랜 시간 기다려야 합니다.
- 외부 트리거가 발생한 후에만 실행됩니다.
- 다시 실행되는 시점을 정확하게 수동으로 제어하고 싶습니다.
- 스케줄러가 실수로 컴퓨터를 깨우는 일이 없도록 하세요.
다음과 같은 경우 작업을 삭제 해야 합니다 .
- 이 작업은 일회성 작업을 완료합니다.
- 스택 메모리를 복구하고 싶습니다.
- 해당 작업은 다시 실행되지 않습니다.
- 불필요한 CPU 사용을 방지하고 싶습니다.
예를 들면 다음과 같습니다.
- 시작 시에만 실행되는 Wi-Fi 설정 작업입니다.
- 한 번 실행되는 센서 보정 작업입니다.
- 사용자가 버튼을 누를 때까지 일시 중지해야 하는 백그라운드 작업입니다.
vTaskSuspend() 및 vTaskResume()을 사용하여 작업 제어
작업 일시 중지 및 재개 기능을 사용하면 작업 일시 중지 시점과 실행 재개 시점을 제어할 수 있습니다. 이는 전력 절약, 불필요한 처리 방지, 실시간 이벤트 기반 시스템 동작 관리에 유용합니다.
ESP32에서는 작업 중단이 두 코어에서 동일한 방식으로 작동하며 FreeRTOS 커널은 안전한 컨텍스트 전환을 보장합니다.
vTaskSuspend() 작동 방식
vTaskSuspend()는 작업의 상태를 준비 상태 또는 실행 상태에서 일시 중지 상태로 변경합니다. 일시 중지된 작업은 CPU 시간을 소비하지 않습니다. 다른 작업과 경쟁하지 않습니다. 단순히 동일한 작업 핸들에 대해 vTaskResume()를 호출할 때까지 대기합니다.

FreeRTOS 작업 상태 다이어그램은 작업이 실행 상태에서 일시 중단 상태로, 그다음 준비 상태로, 다시 실행 상태로 바뀌는 모습을 보여줍니다.
핵심 사항:
- 정지는 즉시 발생합니다.
- 스케줄러는 모든 준비 목록에서 작업을 제거합니다.
- 수동으로 재개하지 않는 한 해당 작업은 다시 실행되지 않습니다.
- 현재 실행 중인 작업을 포함하여 모든 작업을 일시 중단할 수 있습니다 .
특정 이벤트를 기다리는 작업이 있는 워크플로에서 지연이나 통화 차단 대신 전체 수동 제어가 필요한 경우 현재 작업을 일시 중단하는 것이 일반적입니다.
vTaskResume()이 작업을 다시 가져오는 방법
vTaskResume()일시 중단된 작업을 깨워 스케줄러로 반환하는 함수입니다. 이 함수를 호출하면 FreeRTOS는 작업 상태를 Suspended 에서 Ready 로 변경합니다 . 즉, 다음 스케줄링 주기 동안 작업이 다시 실행될 수 있습니다.
중요한 점은 작업을 재개하는 순간 작업이 즉시 실행되지 않는다는 것입니다 . FreeRTOS는 먼저 작업의 우선순위를 확인합니다. 재개된 작업의 우선순위가 현재 실행 중인 작업보다 높으면 스케줄러가 컨텍스트 스위칭을 수행하고 재개된 작업이 작업을 인수합니다. 재개된 작업의 우선순위가 같거나 낮으면, 자신의 차례가 올 때까지 준비 상태로 대기합니다.
작업이 다시 실행되면 중단되었던 바로 그 줄에서 다시 시작됩니다. 아무것도 다시 초기화되지 않으며, 데이터 손실도 없습니다. 이를 통해 vTaskResume()의도적으로 일시 중지되었던 작업을 안전하고 예측 가능하게 다시 활성화할 수 있습니다.
핸들을 사용하여 작업 일시 중단 vs NULL 사용
핸들을 사용하여 특정 작업을 일시 중단할 수 있습니다.
vTaskSuspend(sensorTaskHandle);
하지만 NULL을 전달하여 현재 실행 중인 작업을 일시 중단할 수도 있습니다 .
vTaskSuspend(NULL); // suspend the current task
핸들을 사용해야 하는 경우:
- 한 작업이 다른 작업을 일시 중단하려고 할 때.
- 작업 핸들을 전역적으로 저장하고 외부에서 관리하는 경우.
- 어떤 작업이 일시 중지되었는지 명확히 알아야 할 때.
NULL을 사용하는 경우:
- 작업을 중단해야 할 때.
- 핸들을 전역적으로 노출하고 싶지 않은 경우.
두 형식 모두 동일하게 작동하지만 핸들을 사용하면 앱을 더 쉽게 읽고 디버깅할 수 있으며, 특히 대규모 ESP32 프로젝트에서 그렇습니다.
ESP-IDF 코드 완료(LED 작업 일시 중지 및 재개)
다음은 시스템에서 LED 작업을 실행할 필요가 없을 때 해당 작업을 일시 중지하는 방법을 보여주는 간단한 ESP-IDF 예제입니다.
#include <stdio.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define LED_GPIO 2 // On-board LED for most ESP32 DevKit boards
#define BUTTON_GPIO 0 // BOOT button on DevKit, pulled up by default
TaskHandle_t ledTaskHandle = NULL;
void ledTask(void *pvParameters)
{
int blinkCount = 0;
while (1)
{
// Toggle LED
gpio_set_level(LED_GPIO, 1);
printf("LED ON\n");
vTaskDelay(pdMS_TO_TICKS(300));
gpio_set_level(LED_GPIO, 0);
printf("LED OFF\n");
vTaskDelay(pdMS_TO_TICKS(300));
blinkCount++;
// After 5 blinks, suspend the task
if (blinkCount == 5)
{
printf("Suspending LED Task...\n");
vTaskSuspend(NULL); // Suspend itself
// Reset counter after resume
blinkCount = 0;
}
}
}
void controllerTask(void *pvParameters)
{
while (1)
{
// Button is active LOW
if (gpio_get_level(BUTTON_GPIO) == 0)
{
printf("Button Pressed: Resuming LED Task\n");
vTaskResume(ledTaskHandle);
// Debounce delay
vTaskDelay(pdMS_TO_TICKS(500));
}
vTaskDelay(pdMS_TO_TICKS(50));
}
}
void app_main(void)
{
// Configure LED pin
gpio_reset_pin(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
// Configure button pin
gpio_reset_pin(BUTTON_GPIO);
gpio_set_direction(BUTTON_GPIO, GPIO_MODE_INPUT);
gpio_pullup_en(BUTTON_GPIO); // Button is active-low
gpio_pulldown_dis(BUTTON_GPIO);
// Create tasks
xTaskCreate(ledTask, "LED_Task", 2048, NULL, 5, &ledTaskHandle);
xTaskCreate(controllerTask, "Controller_Task", 2048, NULL, 4, NULL);
}
코드 설명:
LED 작업: LED를 깜박이고 자체 중단
LED 작업은 GPIO 2의 온보드 LED를 전환합니다. LED는 5번 깜박인 후 자동으로 일시 중단됩니다.
중요 사항:
- LED가 몇 초 동안 정상적으로 깜박입니다.
- 5번 깜박이면 작업이 메시지를 인쇄합니다.
- vTaskSuspend(NULL)현재 작업을 일시 중단합니다 .
- LED가 완전히 깜박임을 멈춥니다.
컨트롤러 작업: 버튼 누름을 기다리고 LED 작업 재개
컨트롤러 작업은 GPIO 0의 BOOT 버튼을 모니터링합니다. 이 버튼은 내부적으로 풀업되어 있으므로 누르면 LOW가 됩니다.
사용자가 버튼을 누르면:
- 콘솔에 메시지가 출력됩니다.
- vTaskResume(ledTaskHandle)LED 작업을 깨웁니다.
- LED가 다시 깜박이기 시작합니다.
코드 출력
아래 gif는 작업 중단의 출력을 보여줍니다.

GIF는 LED 작업이 일시 중단되기 전에 LED를 5번 깜빡이는 모습을 보여줍니다. 버튼을 누르면 작업이 재개되고, LED가 다시 5번 깜빡입니다.
위에서 볼 수 있듯이 GPIO2에 연결된 LED가 5번 깜빡인 후 멈춥니다. 이는 LED 작업이 일시 중단된 상태임을 나타냅니다.
버튼을 누르면 LED 작업이 재개되고 LED가 다시 5번 깜빡입니다.
일시 중단/재개 기능을 사용해야 하는 경우
작업을 삭제하지 않고 완전히 일시 중지 하려면 작업 일시 중지 기능을 사용하세요 . 이 기능은 작업이 일정 기간 동안 필요하지 않다가 나중에 다시 필요할 때 유용합니다. 일시 중지 기능을 사용하면 불필요한 CPU 사용량을 방지하고 시스템 효율성을 유지할 수 있습니다.
이벤트나 조건으로 인해 작업이 다시 관련성을 갖게 되면 작업 재개를 사용하세요. 작업이 다시 시작되어 중단된 지점에서 정확히 다시 시작되므로 이 접근 방식은 깔끔하고 예측 가능합니다.
일시 중지/재개 기능은 작업이 일시 중지된 동안 새 데이터나 신호가 필요하지 않을 때 가장 효과적으로 작동합니다. 작업이 다운타임 중에 메시지나 값을 수신해야 하는 경우, 작업 알림이나 대기열이 더 적합합니다.
vTaskDelete()를 사용하여 작업 삭제
FreeRTOS는 작업이 완료된 후 해당 태스크를 완전히 제거할 수도 있습니다. 이는 임시 태스크 생성, 일회성 작업 실행 또는 런타임 중 메모리 해제가 필요할 때 유용합니다. vTaskDelete() 함수는 태스크를 중지하고 할당된 리소스를 해제함으로써 이를 안전하게 처리합니다.
vTaskDelete()가 실제로 하는 일
vTaskDelete()는 스케줄러에서 작업을 영구적으로 제거합니다. 삭제된 작업은:
- 즉시 실행을 중지합니다
- 모든 준비/차단/중단 목록에서 제거됩니다.
- 스택 메모리와 작업 제어 블록(TCB)을 해제합니다.
삭제된 작업은 다시 시작할 수 없습니다. 다시 필요하면 xTaskCreate()로 다시 생성해야 합니다.
자체 삭제 작업 vs 다른 작업 삭제
FreeRTOS에서는 두 가지 삭제 방법이 허용됩니다.
1. 작업 자체 삭제
작업은 다음을 호출하여 자체를 삭제합니다.
vTaskDelete(NULL);
이 함수는 해당 작업이 완료되어 더 이상 존재할 필요가 없을 때 유용합니다. 이 호출 후 FreeRTOS는 메모리를 정리하고 다른 작업으로 전환합니다.
2. 핸들로 다른 작업 삭제
다음을 사용하여 한 작업이 다른 작업을 삭제할 수 있습니다.
vTaskDelete(taskHandle);
유효한 TaskHandle_t.가 필요합니다. 이는 컨트롤러 작업에 전체 제어가 필요할 때 일반적으로 사용됩니다.
실제 예: 작업 완료 후 작업 삭제
아래는 Worker 태스크가 작업을 실행하고, 진행 상황을 출력하고, 완료한 후 자신을 삭제하는 간단한 ESP-IDF 예제입니다 . Monitor 태스크 는 워커를 확인하고 워커가 사라지면 보고합니다.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
TaskHandle_t workerTaskHandle = NULL;
void workerTask(void *pvParameters)
{
for (int i = 1; i <= 5; i++)
{
printf("Worker Task: Step %d/5\n", i);
vTaskDelay(pdMS_TO_TICKS(500));
}
printf("Worker Task: Work complete. Deleting myself...\n");
vTaskDelete(NULL); // Self-delete
}
void monitorTask(void *pvParameters)
{
while (1)
{
if (workerTaskHandle != NULL)
{
eTaskState state = eTaskGetState(workerTaskHandle);
if (state == eDeleted)
{
printf("Monitor Task: Worker Task has been deleted.\n");
workerTaskHandle = NULL; // Avoid using a dead handle
}
}
vTaskDelay(pdMS_TO_TICKS(300));
}
}
void app_main(void)
{
xTaskCreate(workerTask, "WorkerTask", 2048, NULL, 5, &workerTaskHandle);
xTaskCreate(monitorTask, "MonitorTask", 2048, NULL, 4, NULL);
}
코드 설명
작업자 작업
- 5단계의 작업을 수행합니다(시연용으로 인쇄되었습니다).
- 각 단계 사이에 500ms를 기다립니다.
- 작업이 완료되면 vTaskDelete(NULL)을 사용하여 스스로를 삭제합니다.
이는 임시 작업이 작업을 마친 후 어떻게 정리될 수 있는지 보여줍니다.
모니터 작업
- 백그라운드에서 실행됩니다.
- eTaskGetState()를 사용하여 작업자 태스크 상태를 확인합니다.
- 작업자가 삭제된 것을 감지하면 메시지를 인쇄하고 핸들을 지웁니다.
이렇게 하면 삭제된 작업 핸들을 실수로 사용하는 것을 방지할 수 있습니다.
app_main()
- 핸들을 사용하여 작업자 작업을 생성합니다.
- 작업자의 수명 주기를 관찰하는 모니터 작업을 만듭니다.
이 패턴은 작업을 한 번 실행한 후 제거해야 할 때마다 유용합니다.
위의 작업 삭제 코드 출력
아래 이미지는 Espressif-IDE 직렬 터미널에서 작업 삭제 출력을 보여줍니다.

이미지는 Worker 작업이 작업을 완료한 후 삭제되는 모습을 보여줍니다. 모니터 작업은 Worker 작업의 상태를 확인하고 작업이 삭제되었음을 표시합니다.
위에서 볼 수 있듯이 Worker 작업은 작업을 완료한 후 스스로 삭제됩니다. Monitor 작업은 백그라운드에서 Worker 작업의 상태를 계속 확인합니다. 작업이 삭제된 것을 확인하면 콘솔에 메시지를 출력합니다.
작업 삭제 후 메모리 및 스택 정리
FreeRTOS는 자동으로 다음을 정리합니다.
- 작업의 스택 메모리
- 작업 제어 블록(TCB)
- 모든 스케줄러 참조
- 준비, 차단 또는 일시 중단 목록에서 작업의 존재 여부
아래 이미지는 작업이 삭제될 때 FreeRTOS 메모리가 어떻게 정리되는지에 대한 간단한 Before/After 보기를 보여줍니다.

작업을 삭제하기 전과 후의 FreeRTOS 메모리 정리를 보여주는 다이어그램입니다.
왼쪽("작업 삭제 전")에는 RAM에 할당된 작업 제어 블록(TCB)과 작업 스택이 표시되고, 스케줄러의 작업 목록 내부에 작업이 여전히 연결되어 있음을 나타내는 포인터가 표시됩니다.
오른쪽("작업 삭제 후")에서는 이러한 메모리 블록이 "해제된 메모리" 영역으로 바뀌고, 작업이 스케줄러 목록에서 제거되며, 휴지통 아이콘이 작업의 리소스가 완전히 정리되었음을 강조 표시합니다.
따라서 삭제 후에는 해당 메모리를 새로운 작업이나 다른 시스템 용도로 사용할 수 있게 됩니다.
하지만:
- 작업이 동적 메모리를 할당한 경우 별도로 해제해야 합니다.
- 삭제된 작업 핸들은 유효하지 않으므로 사용할 수 없습니다.
이를 통해 작업 삭제는 일회성 작업을 실행하는 안전하고 예측 가능하며 메모리 효율적인 방법이 됩니다.
일시 중지, 재개, 삭제 및 알림 중에서 선택
FreeRTOS는 런타임 시 작업의 동작을 제어하는 여러 가지 방법을 제공합니다. 하지만 적절한 방법을 선택하는 것이 중요합니다. 일시 중단, 재개, 삭제 또는 알림 등 각 옵션은 응답성, 메모리 사용량 및 시스템 안전성에 미치는 영향이 다릅니다. 이 섹션에서는 ESP32 애플리케이션의 효율성과 예측 가능성을 유지하기 위해 어떤 방법을 사용해야 하는지 이해하는 데 도움을 드립니다.
작업 알림 비교
작업 알림(4편 참고)은 작업 간 이벤트를 알리는 가장 가볍고 빠른 방법 입니다 . 힙 메모리를 사용하지 않고 , 오버헤드가 매우 낮으며, 대기 중인 작업을 즉시 해제 할 수 있습니다 .
일시 중지/재개와 비교:
- 새로운 센서 데이터, 버튼 누름, 주기적 작업 등 빈번한 이벤트 에 대해서는 알림이 더 효과적입니다 .
- 이를 통해 실수로 작업이 영구적으로 중단되는 위험을 피할 수 있습니다.
- 이를 통해 작업이 일시 중단 상태가 아닌 차단 상태로 유지될 수 있으며, 스케줄러가 정상적으로 작업을 추적하기 때문에 더 안전합니다.
작업 알림을 사용하는 의도가 신호 → 깨우기 → 계속일 때이고 , 작업을 완전히 중지하는 것이 아닐 때입니다.
작업을 일시 중단하는 것보다 삭제하는 것이 더 안전한 경우
다음과 같은 경우 작업을 삭제하는 것이 좋습니다.
- 이제 작업이 완전히 끝났 습니다 .
- 작업의 스택, TCB 등의 메모리를 해제 해야 합니다 .
- 장기간 중단된 작업이 RAM을 독점하는 것을 피하고 싶습니다.
- 실수로 작업을 나중에 다시 시작해서는 안 됩니다.
다음과 같은 경우 삭제하는 것이 더 안전합니다.
- 일시적이다
- 한 번만 실행됩니다(예: 펌웨어 업데이트 작업)
- 한 번만 교정을 수행합니다.
- 단기 기능(예: Wi-Fi 프로비저닝 작업)을 처리합니다.
작업을 일시 중단하면 메모리가 할당된 상태로 유지되는데, 이는 많은 작업을 장시간 일시 중단할 경우 ESP32에 문제가 될 수 있습니다. 이러한 상황에서 작업을 삭제하면 메모리 누수를 방지하고 시스템 성능을 개선할 수 있습니다.
작업을 완전히 중단하지 않아야 하는 경우
다음과 같은 경우에는 작업을 중단해서는 안 됩니다.
- 이 작업은 응답성을 유지해야 하는 하드웨어 (모터, 통신 인터페이스, 센서) 를 제어합니다.
- 다른 작업은 출력에 따라 달라집니다 .
- 중단된 작업은 논리 버그로 인해 다시 시작되지 않을 수 있습니다.
- 중단된 작업은 지연을 숨기므로 타이밍 문제를 디버깅하고 있습니다.
- 정해진 일정을 원합니다. 일시 중지된 작업이 정상적인 작업 흐름을 방해하기 때문입니다.
일시 중단된 작업은 스케줄러에 표시되지 않습니다. 잘못된 시간에 일시 중단되면 시스템이 정지되거나 예상치 못한 동작을 할 수 있습니다.
정지 대신:
- 더 짧은 일시 정지를 위해 vTaskDelay()를 사용하세요 .
- 제어된 대기를 위해 작업 알림을 사용하세요.
- 큐 , 세마포어 또는 이벤트 그룹 의 블록
- 작업이 영구적으로 완료되면 삭제합니다.
서스펜션은 아껴서 의도적으로 사용해야 합니다.

FreeRTOS 작업 알림, 일시 중단/다시 시작, 작업 삭제 중에서 선택하는 방법을 보여주는 다이어그램입니다.
ESP32 FreeRTOS에서 작업 제어를 위한 모범 사례
작업 관리는 단순히 필요에 따라 일시 중지, 재개 또는 삭제를 호출하는 것이 아닙니다. 시스템의 응답성, 안정성, 그리고 예측 가능성을 유지하는 것이 목표입니다. 이러한 모범 사례는 ESP32에서 작업 제어를 사용할 때 가장 흔히 발생하는 실수를 피하는 데 도움이 됩니다.
우선순위가 높은 작업 차단 방지
우선순위가 높은 작업은 절대로 장시간 중단되거나 차단되어서는 안 됩니다. 이러한 작업은 일반적으로 통신, 인터럽트, 운동 제어와 같이 시간이 중요한 작업을 처리합니다.
높은 우선순위 작업이 너무 오랫동안 차단되는 경우:
- 우선순위가 낮은 작업은 CPU 시간을 결코 얻지 못할 수 있습니다.
- 시스템 타이밍이 예측 불가능해집니다.
- 워치독 재설정이 발생할 수 있습니다
차단하는 대신:
- 짧은 지연을 사용하세요
- 알림 이나 대기열을 사용하세요
- 우선순위가 높은 작업 내부의 작업 부하를 줄이세요
우선순위가 높은 작업은 간소하고 반응성이 좋게 유지하세요.
제어 호출 전에 항상 작업 핸들을 확인하세요
vTaskSuspend(), vTaskResume() 또는 vTaskDelete()와 같은 함수는 유효한 작업 핸들이 필요합니다. 핸들이 NULL이거나 손상된 경우 응용 프로그램이 충돌할 수 있습니다.
작업을 제어하기 전에:
if (taskHandle != NULL)
{
vTaskSuspend(taskHandle);
}
이것은 다음을 방지합니다.
- 생성되지 않은 작업
- 이미 삭제된 작업
- 작업 간 경쟁 조건
핸들을 검증하면 시스템이 안전하게 보호됩니다.
작업 삭제 후 메모리 누수 방지
작업을 삭제하면 스택과 TCB가 해제되지만, 다음의 경우에만 해당됩니다.
- 작업은 xTaskCreate()를 사용하여 생성되었습니다(정적 작업이 아님).
- 다른 코드는 스택 데이터에 대한 참조를 보유하지 않습니다.
- 삭제 후 핸들을 지우거나 재설정합니다.
예를 들어:
vTaskDelete(taskHandle);
taskHandle = NULL; // 실수로 인한 재사용 방지
이 단계를 건너뛰면 이후 코드가 삭제된 작업을 재개하거나 일시 중단하려고 시도할 수 있습니다. 이는 ESP32 시스템에서 무작위 충돌이 발생하는 가장 흔한 원인 중 하나입니다.
결론
이 가이드에서는 ESP32 기반 FreeRTOS의 필수 작업 제어 메커니즘, 즉 작업 일시 중지, 재개, 삭제, 작업 알림 사용에 대해 살펴보았습니다 . 각 메서드의 내부 동작 방식, 스케줄러 내부에서 수정되는 내용, 그리고 메모리 사용량, 응답성, 시스템 안전성 측면에서 각 메서드의 차이점을 알아보았습니다. 실제 사례와 시각적 자료를 통해 각 접근 방식이 언제 적합한지 더 쉽게 이해할 수 있도록 했습니다.
또한 vTaskSuspend()/vTaskResume()이 CPU 시간을 절약하는 데 도움이 되는 실제 시나리오 , vTaskDelete() 가 메모리를 확보하고 사용되지 않는 작업을 정리하는 데 도움이 되는 실제 시나리오, 그리고 작업 알림이 차단 없이 이벤트를 신호로 전달하는 간단한 대안을 제공하는 실제 시나리오도 살펴보았습니다. 의사 결정 트리와 메모리 다이어그램은 센서 폴링부터 임시 백그라운드 작업까지 이러한 도구가 실제 임베디드 애플리케이션에 어떻게 적용되는지 더욱 명확하게 보여주었습니다.
이러한 작업 관리 기법을 숙달하면 더 빠르고 안전하며 예측 가능한 펌웨어를 구축할 수 있습니다 . 일시 중지, 재개, 삭제 또는 알림 중 어떤 것을 선택할지 올바르게 선택하면 시스템 아키텍처가 더욱 깔끔해지고, 리소스 처리가 향상되며, 런타임 시 예상치 못한 문제가 줄어듭니다. 이러한 접근 방식은 예상대로 정확하게 동작하는 확장 가능하고 유지 관리가 간편한 ESP32 프로젝트를 설계하는 데 도움이 됩니다.
튜토리얼 원문을 참고하시려면 이 링크를 따라가세요.
'ESP32' 카테고리의 다른 글
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 1부 (1) | 2025.11.24 |
|---|---|
| ESP-32 LVGL 그래픽을 사용한 고급 기술 - 소개 (0) | 2025.11.24 |
| ESP32 FreeRTOS 구현 살펴보기 (0) | 2025.11.23 |
| FreeRTOS를 사용한 ESP32: 소프트웨어 타이머/타이머 인터럽트 (0) | 2025.11.21 |
| ESP32 FreeRTOS 튜토리얼 가이드 6부작 5 (1) | 2025.11.21 |
| ESP32 ESP-NOW 양방향 커뮤니케이션 (0) | 2025.11.20 |
| esp32 및 esp8266 Dallas ds18b20 네트워크 연결 (0) | 2025.11.19 |
| ESP32 FreeRTOS 튜토리얼 가이드 6부작 4 (1) | 2025.11.19 |
취업, 창업의 막막함, 외주 관리, 제품 부재!
당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약,
아이디어는 있지만 구현할 기술이 없는 막막함.
우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.
이제 고민을 멈추고, 캐어랩을 만나세요!
코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.
제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!
귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.
캐어랩