FreeRTOS의 Task 및 관련 함수
xTaskCreate(), vTaskDelay(), vTaskDelayUntil(), vTaskSuspend(), vTaskResume(), vTaskPrioritySet()
1. Task란?
FreeRTOS에서 태스크 (Task)란 어느 한 시점에서 Running, Suspended, Waiting되어 있는 함수이다.
프로세스(process)나 스레드(thread)와 비슷하게 동작한다.
2. Task의 특징
- Task의 특징과 생김새 각 Task에는 우선순위를 할당하며 숫자가 높을수록 큰 우선순위를 의미한다.
- 우선순위는 0부터 configMAX_PRIORITIES까지 할당이 가능하다.
- 우선순위가 높은 Task는 낮은 Task를 선점(preemption)할 수 있고, 이때 context switching이 발생한다.
- 동일한 우선순위 사이에서는 Round Robin(RR)을 사용한다.
- Task는 return value가 없고 (void*) 타입으로 여러 자료형을 매개변수로 받을 수 있다.
3. Task의 종류
Task는 2가지 종류가 있다.
1. 일회용 task
- 일회용 Task는 기능을 한 번 수행한 뒤 마지막에 스스로를 삭제해야 한다.
void OnlyOneActionTask( void* pvParameters ) {
/* 함수 실행 부 */
vTaskDelete(NULL);
}
2. 주기적 task
- 주기적 Task는 무한 loop가 들어있다.
- Delay 또는 suspend 함수 등으로 Task의 state가 blocked(waiting)로 변하지 않는 이상 계속해서 기능을 빠르게 반복 실행한다.
void ContinuousTask( void* pvParameters ) {
while(true) {
/* 함수 실행 부 */
}
vTaskDelete(NULL); // 실행되지 않음
}
- 각 Task마다 local stack 공간이 할당된다.
- 이 공간은 메모리의 .bss영역 또는 .heap 영역에 들어간다.
- Stack 메모리는 정적 또는 동적으로 할당이 가능하다.
- Stack 메모리 할당은 5가지 방법으로 사용자가 환경설정 할 수 있으며, 메모리 단편화를 막으며 메모리를 할당한다.
- 할당 방법은 동적할당과 정적할당이 존재한다.
4. Task 관련 API
1. xTaskCreate()
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask
);
- pvTaskCode는 Task의 기능이 선언된 함수의 함수포인터를 말한다.
- pcName은 디버깅 용도로 사용하는 문자열이며 Task의 이름을 말한다.
- usStackDepth는 Task마다 할당되는 stack 메모리를 말한다.
- 단위는 WORD이며 1WORD == 4Byte이다.
- pvParameters는 Task 함수로 전달할 매개변수를 말하고 없다면 NULL 이다.
- 전달할 매개변수를 (void*) 타입으로 캐스팅한 뒤 여기다가 넣어주면 Task 함수에서 사용할 수 있다.
- pxCreatedTask는 Task를 제어하기 위한 TaskHandle_t 타입 핸들을 말한다.
- Task의 우선순위를 바꾸거나, Task를 멈추거나 등 Task에 대한 설정은 모두 이 핸들을 통해 제어한다.
ex)
xTaskCreate(exampleTask, “exampleTask”, 128, NULL, 7, &xExampleHandle);
2. vTaskDelay()
void vTaskDelay( TickType_t xTicksToDelay );
- Task의 상태를 Running에서 Blocked(Waiting)으로 변경하는 함수다.
- 설정된 시간 xTicksToDelay동안 해당 Task는 Blocked Task가 되며, 다음 우선순위를 가진 Task가 실행된다.
- MCU별 확장성 및 이식성을 고려하여 tick단위 시간을 사용하는 것 보다 MCU tick을 표현하는 pdMS_TO_TICKS() 매크로를 사용해서 ms(밀리초) 단위를 tick으로 변환해서 사용하거나 pdMS_TO_TICKS()를 사용하는 것이 좋다.
- 이유는 사용하는 MCU 및 사용자의 환경설정되어진 값에 따라 '1' tick이 의미하는 시간이 다르기 때문이다.
3. vTaskDelayUntil()
. - vTaskDelay()와 똑같은 기능을 수행한다.
- vTaskDelay()는 호출 시점부터 지정된 시간만큼 Blocked 되는 반면, vTaskDelayUntil()은 호출 시점과 관계 없이 목표 절대 주기에 맞춰 blocked 된다.
4. vTaskSuspend()
- Task의 우선순위를 바꿀 때 Task를 일단 Blocked state로 만들 필요가 있을 때 주로 사용한다.
- 혹은 Task가 특정 조건에 동작하지 않게 하고 싶을 때 사용한다.
- Delay 함수는 Task를 일정 시간동안 Blocked state로 만들지만, vTaskSuspend()함수는 Task를 기약없이 Blocked state로 만든다.
5. vTaskResume()
- vTaskSuspend()되어 Blocked state에 들어간 Task는 vTaskResume()함수를 사용하여 Blocked state를 벗어나게 할 수 있다.
- Task의 handle로 해당 Task를 Blocked 상태로 만들거나 해제하는 것을 제어할 수 있다.
6. vTaskPrioritySet()
- Task의 우선순위를 바꾼다.
- 우선 순위를 바꾸기전 vTaskSuspend()를 사용해 주어야 한다.
- Task의 handle로 우선순위를 바꿀 Task를 선택할 수 있다.
'임베디드 관련 > FreeRTOS' 카테고리의 다른 글
[FreeRTOS] Critical Section(임계 영역), 공유자원 보호하기 (0) | 2024.06.10 |
---|---|
[FreeRTOS] Task의 Stack 최적의 사이즈 설정 (0) | 2024.05.30 |
[FreeRTOS] Task의 우선순위와 선점 (0) | 2024.05.18 |
[FreeRTOS] FreeRTOS 네이밍 규칙 (0) | 2024.05.07 |
[FreeRTOS] FreeRTOS란? (0) | 2024.05.06 |
댓글