[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 마다 동작이 수행된다.


이 블로그의 인기 게시물