4번째 포스팅에서 Task를 만드는 방법에 대해 알아봤고, 5번째 포스팅에서는 Task 상태에 대해 알아봤다.(아래 링크 참고)
https://vuzwa.tistory.com/entry/5-Free-RTOS-Task-%EC%83%81%ED%83%9C%EC%99%80-%EB%8F%99%EC%9E%91
Task를 만들고, 상태에 대해서도 알아봤으니 이제 본격적으로 Task를 제어해보자.
1. Ready -> Running -> Blocked
이전 포스팅에서 설명한 것과 같이 vTaskDelay() 함수를 호출하게 되면 지정된 시간 동안 Task는 Blocked 상태가 되었다가 지정된 시간이 지나면 이벤트가 발생해 다시 Ready 상태가 된 다음 Running 상태가 되어 Task가 동작하게 된다.
vTaskDelay() 함수는 정확한 시간 단위가 아니라 CPU의 Frequency를 기준으로 동작한다. pdMS_TO_TICKS함수를 이용하면 정확한 msec값으로 Delay를 시킬 수 있다. 코드를 통해 동작을 살펴보자.
Task 생성
xTaskCreate( vTask1, /* Pointer to the function that implements the task*/
"Task1", /* text name*/
128, /* stack depth */
NULL, /* task parameter. */
3, /* task priority */
&xTask1Handle); /* task handle */
xTaskCreate( vTask2, "Task2", 128, NULL, 4, &xTask2Handle);
xTask1Handle, xTask2Handle를 각각 추가해줬다. 이 두 변수 선언은
TaskHandle_t xTask1Handle;
TaskHandle_t xTask2Handle;
Task 함수
void vTask1(void *pvParameters)
{
while(1) {
printf("Operate in Task1\r\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vTask2(void *pvParameters)
{
while(1) {
printf("Operate in Task2\r\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
동작을 확인해보자.
우선순위가 높은 Task2 먼저 실행되고, 100 msec 동안 Task2는 Blocked 상태가 된다. Task2가 Blocked 상태가 되면 Ready 상태에 있던 Task1이 Running 상태가 되어 동작하고 100 msec 동안 Blocked 상태가 된다.
Task2에서 vTaskDelay 함수를 호출한 순간부터 100 msec가 지나면 이벤트가 발생해 Task2는 Ready 상태가 되고, CPU를 점유하고 있는 Task가 없기 때문에 바로 Running 상태로 변환돼서 동작을 수행한다.
이 과정을 연속적으로 반복한다.
이 외에도 vTaskDelayUntil(), xTaskDelayUntil(), xTaskAbortDelay() 함수가 있는데 일반적으로 vTaskDelay() 함수를 많이 사용한다.
2. Ready -> Running -> Suspended
vTaskCreate() 함수로 Task를 만들면 Ready에서 Running 상태로 자동으로 변경된다. 여기서 Task를 Suspended 상태로 변경하는 방법은 vTaskSuspended 함수를 호출하면 된다.
지금부터 Task 생성 방법은 생략하도록 하겠다.
Task1, Task2 함수를 아래와 같이 작성하고 동작을 확인해보자.
void vTask1(void *pvParameters)
{
uint16_t cnt = 0;
while(1) {
printf("Operate in Task1\r\n");
cnt++;
if(cnt > 5) {
printf("---Suspend Task1\r\n");
vTaskSuspend(NULL);
cnt = 0;
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vTask2(void *pvParameters)
{
while(1) {
printf("Operate in Task2\r\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
"Operate in Task1", "Operate in Task2"을 번갈아가면서 출력하고 "---Suspend Task1"을 출력한 다음부터는 "Operate in Task2"만 출력하는 것을 확인할 수 있다.
vTaskSuspend(NULL) 호출로 Task1을 Suspended 상태로 만들었기 때문이다.
vTaskSuspend함수의 매개변수에 NULL을 전달하면 자기 자신을 Suspended 상태로 만든다.
Task1에서 Task2를 Suspended 상태로 만들어보자.
void vTask1(void *pvParameters)
{
char* str = pcTaskGetName(xTask2Handle);
while(1) {
printf("Operate in Task1\r\n");
if(eSuspended != eTaskGetState(xTask2Handle)) {
printf("Suspend %s\r\n", str);
vTaskSuspend(xTask2Handle);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vTask2(void *pvParameters)
{
while(1) {
printf("Operate in Task2\r\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
vTask1 함수에서 처음 보는 pcTaskGetName() 함수와 eTaskGetState() 함수가 보인다. pcTaskGetName 함수는 특별한 설정 없이 불러와 사용하면 되고, eTaskGetState() 함수는 CubeMX에서 설정을 변경해 줘야 한다.
잠시 CubeMX로 이동해보자.
Middleware에서 FREERTOS를 선택하고 Include parameter메뉴를 보면 추가할 수 있는 함수가 나와있다. 이 중에서 "eTaskGetState" 함수를 Enable로 변경하고 다시 code generate 하면 eTaskGetState함수를 사용할 수 있다.
동작을 확인해보면,
Task2, Task1 순서로 실행된 다음 "Suspend Task2" 메시지 이후 Task1만 실행되는 것을 확인할 수 있다.
내용을 정리하자면,
1. Task를 Suspend 상태로 만들기 위해서는 vTaskSuspend 함수를 사용해야 한다.
2. vTaskSuspend함수의 매개변수에 NULL을 전달하면 자기 자신을 Suspended 상태로 만든다.
3. vTaskSuspend함수의 매개변수에 다른 Task의 Handle을 전달하면 해당 Task를 Suspended 상태로 만든다.
3. Ready -> Running -> Suspended -> Ready -> Running
Task를 Suspended 상태에서 다시 시작하려면 vTaskResume() 함수를 호출해주면 된다. 아래 코드를 보자.
void vTask1(void *pvParameters)
{
char* str = pcTaskGetName(xTask2Handle);
while(1) {
printf("Operate in Task1\r\n");
if(eSuspended == eTaskGetState(xTask2Handle)) {
printf("Resume %s\r\n", str);
vTaskResume(xTask2Handle);
}
else if(eSuspended != eTaskGetState(xTask2Handle)) {
printf("Suspend %s\r\n", str);
vTaskSuspend(xTask2Handle);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vTask2(void *pvParameters)
{
while(1) {
printf("Operate in Task2\r\n");
vTaskDelay(pdMS_TO_TICKS(100));
}
}
동작은 아래 log를 통해 확인
Task의 동작상태를 이해했다면 충분히 이해 가능하다고 생각한다. 혹시 궁금한 부분이 있다면 댓글 달아주세요.
- 끝 -
'OS(운영체제) > FreeRTOS' 카테고리의 다른 글
8. Free RTOS - Heap Memory Management, 메모리 관리 (1) | 2024.11.15 |
---|---|
7. Free RTOS - Data Types and Coding Style Guide (0) | 2022.11.09 |
5. Free RTOS - Task 상태와 동작 (0) | 2022.11.08 |
4. Free RTOS - Task 생성하기, Multi Task(with STM32L475VGT, B-L475E-IOT01A1) (0) | 2022.11.07 |
3. Free RTOS - CMSIS_RTOS vs FreeRTOS (0) | 2022.11.02 |