[FreeRTOS] vTaskDelayUntil : Task Blocking API
[FreeRTOS] vTaskDelay : Task Blocking API
이전 포스트에서 vTaskDelay 함수를 사용하여 1초마다 로그를 찍도록 했는데,
xTaskGetTickCount( ) API를 사용하여 Tick 카운트를 찍어보니,
1초(파란색)마다 찍는듯 보이지만... ms단위(빨간색)에서 점점 조금씩 밀리는걸 볼 수 있다.
{ 변수를 증가 (i++) 하고, 함수 (printf) 를 호출하는 만큼.. 지연 됨 }

결국 밀리고 밀리다보면, 초 단위까지 넘어가게 된다.

이렇게 점점 밀리는 것을 방지하기 위해 다음 방법을 사용해 보자.
# vTaskDelayUntil를 호출하는 Task는 첫번째 인자로 넘겨주는 시간을 기준으로 절대 시간에 도달할 때까지 'Blocked' 상태가 된다.
#Pre-Condition
// FreeRTOSConfig.h
#define INCLUDE_vTaskDelayUntil 1
# Example
#include "main.h"
#include "cmsis_os.h"
#include <stdio.h>
#define TASK_MAIN_PRIO 20
#define TASK_2_PRIO 9
static void TaskMain(void const *pvParameters);
static void Task2(void const *pvParameters);
TaskHandle_t xHandleMain, xHandle2;
void MAIN_THREAD(void)
{
xTaskCreate((TaskFunction_t)TaskMain, "TaskMain" , 256, NULL, configMAX_PRIORITIES, &xHandleMain);
}
static void TaskMain(void const *pvParameters)
{
const char *pcTaskName = "TaskMain";
UNUSED(pvParameters);
printf("[%s] is running\n", pcTaskName);
xTaskCreate((TaskFunction_t)Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_2_PRIO, &xHandle2);
vTaskDelete(xHandleMain);
}
static void Task2(void const *pvParameters)
{
const char *pcTaskName = "Task2";
unsigned int i = 0U;
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS(1000);
UNUSED(pvParameters);
printf("[%s] is running\n", pcTaskName);
xLastWakeTime = xTaskGetTickCount();
while(1)
{
printf("[%lu] %u\n", xTaskGetTickCount(), i);
i++;
vTaskDelayUntil(&xLastWakeTime, xPeriod);
}
}
시간이 밀리지 않고, 정해진 Period 마다 동작이 수행된다.
