FreeRTOS

FreeRTOS Task

임베디드 친구 2025. 1. 12. 16:06
반응형

CMSIS-RTOS v1 소개

CMSIS-RTOS v1은 ARM에서 제공하는 Cortex-M 마이크로컨트롤러를 위한 RTOS 인터페이스 표준입니다. 이 표준은 다양한 RTOS 구현에서 동일한 API를 사용할 수 있도록 설계되었으며, 코드 이식성을 높이는 데 기여합니다. 이를 통해 애플리케이션 개발자는 RTOS 자체의 세부 구현보다는 애플리케이션 로직에 더 집중할 수 있습니다.

CMSIS-RTOS v1의 핵심 기능 중 하나는 태스크(Task) 관리입니다. 태스크는 RTOS에서 실행되는 독립적인 작업 단위이며, 멀티태스킹 환경에서 중요한 역할을 합니다. 이 글에서는 CMSIS-RTOS v1에서 태스크를 생성하고 관리하는 방법을 단계별로 알아보겠습니다.


CMSIS-RTOS v1에서 태스크 생성 방법

CMSIS-RTOS v1에서 태스크를 생성하려면 다음과 같은 단계가 필요합니다:

  1. 태스크를 정의합니다.
  2. 태스크 속성을 설정합니다.
  3. osThreadNew() 함수를 호출하여 태스크를 생성하고 실행합니다.

태스크 정의

태스크는 일반적으로 void 타입의 함수로 정의됩니다. 이 함수는 태스크가 실행할 작업을 포함합니다.

void TaskFunction(void *argument) {
    while (1) {
        // 태스크 작업 수행
        osDelay(1000); // 1초 대기
    }
}

태스크 속성 설정 및 태스크 생성

osThreadNew() 함수를 사용하여 태스크를 생성합니다. 이 함수는 다음 인수를 사용합니다:

  • void (*func)(void *): 태스크 함수
  • void *argument: 태스크에 전달할 인자
  • const osThreadAttr_t *attr: 태스크 속성

아래는 태스크 생성 예제입니다:

#include "cmsis_os2.h"

void TaskFunction(void *argument);

int main(void) {
    // RTOS 커널 초기화
    osKernelInitialize();

    // 태스크 생성
    osThreadId_t taskHandle = osThreadNew(TaskFunction, NULL, NULL);

    // 커널 시작
    osKernelStart();

    while (1) {
        // 메인 루프
    }
}

태스크의 상태 및 전환

CMSIS-RTOS v1에서 태스크는 다음과 같은 상태를 가질 수 있습니다:

  1. Running: 현재 실행 중인 상태입니다.
  2. Ready: 실행 대기 중인 상태입니다.
  3. Blocked: 특정 이벤트(예: 신호, 메시지, 시간 대기)를 기다리는 상태입니다.

태스크 상태는 RTOS 스케줄러에 의해 관리되며, 태스크 간 컨텍스트 전환(Context Switching)이 이루어집니다. 예를 들어, 태스크가 osDelay()를 호출하면 Blocked 상태로 전환되고, 대기 시간이 끝나면 다시 Ready 상태로 전환됩니다.

예제: 상태 전환 시뮬레이션

void TaskFunction(void *argument) {
    while (1) {
        // Running 상태
        osDelay(1000); // Blocked 상태로 전환
    }
}

osThreadNew() 함수와 태스크 정의

osThreadNew()는 태스크를 생성하는 데 사용되는 핵심 함수입니다. 이 함수는 CMSIS-RTOS v1의 태스크 관리 기능을 제공하며, 사용 방법은 다음과 같습니다:

osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
  • func: 실행할 태스크 함수
  • argument: 태스크에 전달할 인자
  • attr: 태스크 속성 (NULL일 경우 기본 속성이 사용됨)

태스크 속성 정의 예제

태스크 속성은 osThreadAttr_t 구조체를 사용하여 정의할 수 있습니다. 이 구조체는 태스크 이름, 스택 크기, 우선순위 등을 포함합니다.

const osThreadAttr_t taskAttributes = {
    .name = "MyTask",
    .priority = osPriorityNormal,
    .stack_size = 512
};

osThreadId_t taskHandle = osThreadNew(TaskFunction, NULL, &taskAttributes);

태스크 간 통신과 기본적인 협력 작업 구현

RTOS 환경에서 태스크 간 협력은 주로 메시지 큐, 신호, 또는 세마포어를 통해 이루어집니다. CMSIS-RTOS v1은 이러한 메커니즘을 제공합니다.

메시지 큐를 사용한 통신 예제

메시지 큐를 사용하면 태스크 간 데이터를 안전하게 전달할 수 있습니다.

#include "cmsis_os2.h"

osMessageQueueId_t messageQueue;

void SenderTask(void *argument) {
    uint32_t message = 42;
    while (1) {
        osMessageQueuePut(messageQueue, &message, 0, osWaitForever);
        osDelay(1000);
    }
}

void ReceiverTask(void *argument) {
    uint32_t receivedMessage;
    while (1) {
        osMessageQueueGet(messageQueue, &receivedMessage, NULL, osWaitForever);
        // 메시지 처리
    }
}

int main(void) {
    osKernelInitialize();

    // 메시지 큐 생성
    messageQueue = osMessageQueueNew(10, sizeof(uint32_t), NULL);

    // 태스크 생성
    osThreadNew(SenderTask, NULL, NULL);
    osThreadNew(ReceiverTask, NULL, NULL);

    osKernelStart();

    while (1) {
        // 메인 루프
    }
}

결론

CMSIS-RTOS v1은 태스크 생성, 상태 관리, 태스크 간 통신 등 RTOS의 핵심 기능을 쉽게 구현할 수 있도록 돕습니다. 이를 통해 애플리케이션 개발자는 멀티태스킹 환경에서 안정적이고 효율적인 코드를 작성할 수 있습니다.

위에서 설명한 내용을 바탕으로 다양한 태스크 관리 기술을 익히고 실제 프로젝트에 적용해 보세요. 이를 통해 보다 효율적인 임베디드 시스템 개발이 가능할 것입니다.

반응형