[FreeRTOS] SOFTWARE TIMER (소프트웨어 타이머)

# Software Timer Config


configUSE_TIMERS는 디폴트로 0이지만 타이머를 사용하기 위해서는 반드시 1로 변경 되어야 한다.

그외 나머지는 적당히 알아서 셋팅 하도록 하자.

// FreeRTOSConfig.h

/* Software timer definitions. */
#define configUSE_TIMERS                         1 // Required
#define configTIMER_TASK_PRIORITY                3
#define configTIMER_QUEUE_LENGTH                 10
#define configTIMER_TASK_STACK_DEPTH             configMINIMAL_STACK_SIZE


# Software Timer API

xTimerCreate : 타이머 생성

#include “timers.h”

TimerHandle_t xTimerCreate(const char *pcTimerName, 
 const TickType_t xTimerPeriod, 
 const UBaseType_t uxAutoReload, 
 void * const pvTimerID, 
 TimerCallbackFunction_t pxCallbackFunction);
 
 // # Parameters
 //  pcTimerName : 타이머 이름
 //  xTimerPeriod : 타이머 주기 (Tick 단위) 
 //                 단위를 ms 로 변경하기위해 pdMS_TO_TICKS 매크로를 사용 함.
 //                 ex) 500ms => pdMS_TO_TICKS(500)
 //  uxAutoReload : 타이머 작동 방식 설정
 //                 pdFALSE : one-shot 타이머
 //                 pdTRUE  : auto-reload 타이머
 //  pvTimerID : 타이머 ID, vTimerSetTimerID() API를 사용하여 업데이트 가능
 //              동일한 콜백 함수가 여러 타이머에 할당 된 경우,
 //              타이머 ID를 콜백 함수 내에서 체크하여 어떤 타이머에서 호출했는지 구분 가능 함
 //  pxCallbackFunction : 타이머 시간이 만료 되었을 때 호출되는 함수
 //                       콜백함수 프로토 타입은 다음과 같음
 //                       void vCallbackFunctionExample(TimerHandle_t xTimer);
 
 // # Return Values
 //  NULL : 힙 메모리가 충분하지 않아 타이머 데이터 구조체 할당에 실패 하는 경우
 //  timer_handle : 타이머를 참조 할 수 있는 핸들 (타이머 생성 성공)

원샷 타이머는 말 그대로 한 번만 콜백함수가 불리게 되는 타이머 이고,

오토 리로드 타이머는 콜백함수가 반복해서 불리게 된다.

Javascript에서의 SetTimeout( ) 과 SetInterval( ) 이라고 생각 하면 되겠다.


타이머는 core FreeRTOS 코드가 아니라 타이머 서비스(또는 데몬) task에 의해 제공 되며,
FreeRTOS 타이머 API는 타이머 커맨드 큐라고 불리는 큐로 커맨드를 보냄.


xTimerIsTimerActive : 타이머 실행 상태 여부

다음과 같은 경우 타이머가 실행되지 않음을 의미 함.

1. 타이머가 생성되었지만 시작되지 않았음.
2. 타이머가 만료된 후 다시 시작되지 않은 One-Shot 타이머
#include “timers.h”
BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer);

// # Parameters
//  xTimer : 타이머 핸들

// # Return Values
//  pdFALSE : 타이머 실행 중 아님
//  Any other value : 타이머 실행 중

Example

void vAFunction( TimerHandle_t xTimer )
{    
    if( xTimerIsTimerActive( xTimer ) != pdFALSE ) 
    {
        /* Timer Active 상태 */
    }
    else
    {
    	/* Timer Inactive 상태 */
    }
}


xTimerStart : 타이머 시작

타이머를 시작 함.
xTimerStartFromISR( )은 ISR(Interrupt Service Routine) 에서 호출 할 수 있는 기능이 똑같은 함수 임.

타이머가 이미 실행중이 아닌 경우, 타이머는 xTimerStart( )가 호출된 시점으로부터 만료 시간을 계산 함.
타이머가 이미 실행 중이면 xTimerStart( )는 기능적으로 xTimerReset( )과 동일 함.
#include “timers.h”

BaseType_t xTimerStart(TimerHandle_t xTimer, TickType_t xTicksToWait);

// # Parameters
//  xTimer : 타이머 핸들
//  xTicksToWait : 타이머 커맨드 큐가 가득 찬 경우, 타이머 커맨드 큐가 사용가능 해질 때 까지 
//                 task가 blocked 상태로 남아 있어야 하는 시간을 지정 함.
//                 portMAX_DELAY로 설정하면 무기한 대기 하게 됨.

// # Return Values
//  pdPASS : Start 커맨드가 성공적으로 타이머 커맨드 큐에 전송 됨.
//  pdFAIL : 타이머 커맨드 큐가 가득 차, Start 커맨드 전송 실패 함.


xTimerReset : 타이머 재 설정

타이머를 다시 설정 함. (클리어 또는 캔슬의 리셋이 아님)
xTimerResetFromISR( )은 ISR(Interrupt Service Routine) 에서 호출 할 수 있는 기능이 똑같은 함수 임.

타이머가 이미 실행 중일 때, xTimerReset( )이 호출된 시간을 기준으로 만료 시간을 다시 계산 함.
타이머가 실행 중이 아닌 경우, 기능적으로 xTimerStart( )와 동일 함.


xTimerChangePeriod : 타이머 기간(주기) 변경

타이머의 기간(주기)을 변경 함.
xTimerChangePeriodFromISR( )은 ISR(Interrupt Service Routine) 에서 호출 할 수 있는 기능이 똑같은 함수 임.

타이머가 이미 실행 중일 때, 호출 시점을 기준으로 만료 시간이 다시 계산 됨.
타이머가 실행 중이지 않은 경우, 새로운 기간(주기) 값을 사용하여 만료 시간을 계산하고 타이머가 시작 됨.
#include “timers.h”

BaseType_t xTimerChangePeriod(TimerHandle_t xTimer, TickType_t xNewPeriod,TickType_t xTicksToWait);

// # Parameters
//  xTimer : 타이머 핸들
//  xNewPeriod : 새로운 타이머 기간(주기)
//  xTicksToWait : 타이머 커맨드 큐가 가득 찬 경우, 타이머 커맨드 큐가 사용가능 해질 때 까지 
//                 task가 blocked 상태로 남아 있어야 하는 시간.
//                 portMAX_DELAY로 설정하면 무기한 대기 하게 됨.

// # Return Values
//  pdPASS : Change Period 커맨드가 성공적으로 타이머 커맨드 큐에 전송 됨.
//  pdFALSE : 타이머 커맨드 큐가 가득 차서, Change Period 커맨드 전송 실패 함.


xTimerStop : 타이머 정지

타이머 정지(취소) 함
xTimerStopFromISR( )은 ISR(Interrupt Service Routine) 에서 호출 할 수 있는 기능이 똑같은 함수 임.
#include “timers.h”

BaseType_t xTimerStop(TimerHandle_t xTimer, TickType_t xTicksToWait);

// # Parameters
//  xTimer : 멈출 타이머의 핸들
//  xTicksToWait : 타이머 커맨드 큐가 가득 찬 경우, 타이머 커맨드 큐가 사용가능 해질 때 까지 
//                 task가 blocked 상태로 남아 있어야 하는 시간을 지정 함.
//                 portMAX_DELAY로 설정하면 무기한 대기 하게 됨.

// # Return Values
//  pdPASS : Stop 커맨드가 성공적으로 타이머 커맨드 큐에 전송 됨.
//  pdFALSE : 타이머 커맨드 큐가 가득 차서, Stop 커맨드 전송 실패 함.


xTimerDelete : 타이머 삭제

#include “timers.h”
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xTicksToWait);

// # Parameters
//  xTimer : 삭제하려는 타이머의 핸들
//  xTicksToWait : 타이머 커맨드 큐가 가득 찬 경우, 타이머 커맨드 큐가 사용가능 해질 때 까지 
//                 task가 blocked 상태로 남아 있어야 하는 시간을 지정 함.
//                 portMAX_DELAY로 설정하면 무기한 대기 하게 됨.


// # Return Values
//  pdPASS : Delete 커맨드가 성공적으로 타이머 커맨드 큐에 전송 됨.
//  pdFALSE : 타이머 커맨드 큐가 가득 차서, Delete 커맨드 전송 실패 함.


xTimerGetExpiryTime : 타이머가 만료 되어 타이머의 콜백 함수가 실행되는 시간 반환

#include “timers.h”

TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer);

// # Parameters
//  xTimer : 타이머 핸들

// # Return Values
//  xRemainingTime :
//  xTimer가 참조하는 타이머가 활성화 되어 있으면 타이머의 콜백 함수가 다음에 실행 될 시간이 반환 됨.
//  시간은 RTOS Tick으로 지정 됨.

//  xTimer가 참조하는 타이머가 비활성화 상태라면 반환 값은 정의 되지 않음.

//  타이머의 활성화 여부는 xTimerIsTimerActive() API를 사용하여 확인 할 수 있음.

Example

static void vAFunction( TimerHandle_t xTimer )
{
/*
    xTimer가 참조하는 타이머가 만료되기까지 남은 시간을 계산
    TickType_t 는 unsigned 타입
*/

	TickType_t xRemainingTime;
 
 	xRemainingTime = xTimerGetExpiryTime( xTimer ) - xTaskGetTickCount();
}


pcTimerGetName : 타이머 이름 반환

#include “timers.h”

const char * pcTimerGetName(TimerHandle_t xTimer);

// # Parameters
//  xTimer : 타이머 핸들

// # Return Values
//  타이머 이름에 대한 포인터. 표준 NULL 문자로 끝나는 C 문자열.


pvTimerGetTimerID : 타이머 ID 반환

타이머에 할당 된 식별자 (ID) 를 반환 함. 식별자는 타이머 생성시 할당 되며,
vTimerSetTimerID( ) API를 사용하여 업데이트 할 수 있음.

동일한 콜백 함수가 여러 타이머에 할당된 경우, 타이머 식별자는 어떤 타이머에 의해 호출되었는지 구분 하게 해줌.
#include “timers.h”

void *pvTimerGetTimerID(TimerHandle_t xTimer);

// # Parameters
//  xTimer : 타이머 핸들

// # Return Values
//  쿼리 중인 타이머에 할당 된 식별자

Example) 아래 예제는 Timer 구분이 아니라, 데이터 저장을 용도로 사용 함.

void TimerCallbackFunction( TimerHandle_t pxExpiredTimer )
{
	uint32_t ulCallCount;
    
/*
	타이머가 만료되어 콜백 함수를 실행한 횟수는 타이머의 ID에 저장 됨
	ID를 받아와서 증가시키고, 다시 ID에 저장 함.
*/

    ulCallCount = ( uint32_t ) pvTimerGetTimerID( pxExpiredTimer );
    ulCallCount++;
    vTimerSetTimerID( pxExpiredTimer, ( void * ) ulCallCount );
}


이 블로그의 인기 게시물

Crusader Kings 3 - Converting DNA code using Portrait Editor