지식이 늘었다/RTOS

Task란 무엇인가?, xTaskCreate, xTaskDelete

PurpleGuy101 2025. 4. 11. 09:15

-1.

스케쥴링, Concurrency와 Parallelism(Multitasking), 컨텍스트 스위칭에 관한 내용

https://freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/01-RTOS-fundamentals

 

RTOS Fundamentals - FreeRTOS™

Links to RTOS concept pages

freertos.org

 

Task Create API에 관한 정보

https://freertos.org/Documentation/02-Kernel/04-API-references/01-Task-creation/00-TaskHandle

 

 

0.

 

RTOS에서 돌아가는 Application은

 

온도를 측정해서 표시해주는 어플리케이션이 있다고 한다면,

 

센서데이터를 Gather하고, Display를 update하고, UserInput을 처리하는

3가지 작업들로 나눌 수 있다.

 

Task는 어플리케이션의 일부 작업들을 의미한다.

 

1.

 

FreeRTOS 커널에서 Task를 수행하고 싶다면

 

(1) 이러한 Task를 만들고,

(2) 실제 머신에게 Task를 Implement하는 

과정이 필요하다.

 

2.

 

사용자는 FreeRTOS가 제공하는 xTaskCreate() API를 사용하여 태스크를 생성할 수 있다.

BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode,
	const char * const pcName,
    unsigned short usStackDepth,
    void *pvParameters,
    UBaseType_t uxPriority,
	TaskHandle_t *pxCreatedTask
)

 

등록된 태스크는 FreeRTOS 커널에 의해 스케줄링되며,

지정된 태스크 함수(pvTaskCode)가 실행된다.

void vKeyHandlerTask( void *pvParameters) {
	
    //  Task는 일반적으로 무한 루프 내에서 실행된다.
    for(;;){
        //Task Applcation Code
        [Block to wait for a key press event]
        [Process the key press]
    }
    // -> 만약 이 무한루프를 탈출한다면, 해당 Task는 삭제되어야한다.
    vTaskDelete( NULL );
}

 

3.

 

https://freertos.org/Documentation/02-Kernel/04-API-references/01-Task-creation/01-xTaskCreate

 

사실 API나 라이브러리나 모듈이란게 늘 그렇듯이, 

함수에 입력되는 파라미터(엄밀히는 아규먼트)를 알면 되는 경우가 대부분이다.

Task Create와 Task Delete를 하는 과정은 커널 내부에서 처리된다.

우리는 API에 어떤 입력값이 필요한지 알면된다.

 

 BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
                         const char * const pcName,
                         const configSTACK_DEPTH_TYPE uxStackDepth,
                         void *pvParameters,
                         UBaseType_t uxPriority,
                         TaskHandle_t *pxCreatedTask
                       );

 

 

TaskFunction_t pvTaskCode -  Task가 사용하는 Task handler의 Address이다.


const char * const pcName - 해당 Task를 구분하기 위한 Task명을 정해주자..


const configSTACK_DEPTH_TYPE uxStackDepth, - 해당 Task에 할당할 스택의 크기를 설정해주자.

단위는 Byte가 아니라, Word이다.

스택이 16bit(=2byte)를 하나의 Word단위로 사용하고,

uxStackDepth가 100이라면, 실제로 할당되는 스택메모리공간은 2byte * 100word = 200byte가 된다.

똑같이 스택이 32bit(=4byte) 단위로 1word를 이루고, uxStackDepth를 400으로 설정해준다면

4byte * 400 = 1600byte가 해당 테스크에 할당되는 스택메모리공간이 된다. 

 

(-> Intel x86 ISA나 SIMD를 배우면서 Word, DWord같은 단위를 배운적이 있다.

하나의 Word란 대개 프로세서가 Single Instruction, Single Clock Cycle에 처리 할 수 있는 비트의 단위이다.

Intel에서 DoubleWord가 16bit가 된 것은, 8086시절 즈음의 8bit레지스터를 기준으로 1Word를 정의했기 때문이다.

1960년대에 IBM에서 8bit를 하나의 binary term으로 정의해서 1Byte가 된 것과

1970년대에 4bit의 단위는 nibble이라고 칭하기 시작한 것도 기억해둘만하다.)


void *pvParameters, - 스케쥴링되었을 때 task Handler에 입력될 특정 데이터의 포인터이다.


UBaseType_t uxPriority, - 해당 Task의 Priority, 우선순위이다.


TaskHandle_t *pxCreatedTask -

이 값은 NULL이 디폴트값이고, 굳이 안 설정해줘도 된다고한다.

뭐하는데 쓰는지는 모르겠다

 

-> 이러한 방식을 통해서 xTaskCreate()

pdPASS값이 Return된다.아니면 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY가 Return 된다.

 

 

4.아래의 예제 코드를 보면 대강 어떻게 사용되는지 이해가 될 것이다.

/* Task to be created. */
void vTaskCode( void * pvParameters )
{
    /* The parameter value is expected to be 1 as 1 is passed in the
       pvParameters value in the call to xTaskCreate() below. */

    configASSERT( ( ( uint32_t ) pvParameters ) == 1 );

    for( ;; )
    {
        /* Task code goes here. */
    }
}

/* Function that creates a task. */
void vOtherFunction( void )
{
    BaseType_t xReturned;
    TaskHandle_t xHandle = NULL;

    /* Create the task, storing the handle. */
    xReturned = xTaskCreate(
                    vTaskCode,       /* Function that implements the task. */
                    "NAME",          /* Text name for the task. */
                    STACK_SIZE,      /* Stack size in words, not bytes. */
                    ( void * ) 1,    /* Parameter passed into the task. */
                    tskIDLE_PRIORITY,/* Priority at which the task is created. */
                    &xHandle );      /* Used to pass out the created task's handle. */

    if( xReturned == pdPASS )
    {
        /* The task was created. Use the task's handle to delete the task. */
        vTaskDelete( xHandle );
    }
}

 

 

 

5.이후에 Task Handler에서 Task 루프가 종료되면수행되는 vTaskDelete이다.입력파라미터에 NULL이 입력되면, 해당 Task를 종료하고 배정된 메모리공간을 회수한다.

 

void vTaskDelete( TaskHandle_t xTask );

 

 

void vOtherFunction( void )
{
    TaskHandle_t xHandle = NULL;

    // Create the task, storing the handle.
    xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );

    // Use the handle to delete the task.
    if( xHandle != NULL )
    {
        vTaskDelete( xHandle );
    }
}