STM32/STM32_RTOS

STM32 RTOS 알아보기 4편(xTimerCreate,xTimerStart,xTimerStop)

원원 2025. 1. 28. 10:26

안녕하세요. 오늘은 RTOS에서 사용하는 타이머를 알아보겠습니다.

우선 이전글에서는 인터페이스를 CMSIS_V1로 사용했었는데 해당버전을 사용하면 타이머를 사용할때 다른코드를 추가해줘야하는게 있으므로 CMSIS_V2로 변경해서 사용하겠습니다.

CMSIS_V2버전으로 바꾸고 빌드할때 freertos_mpool.h: no such file or directory와같은 에러가 나올수도 있는데 F103기준으로 펌웨어패키지 버전을 STM32Cube FW_F1 V1.8.5로 바꾸니 빌드가 됐습니다.



* xTimerCreate함수
TimerHandle_t xTimerCreate(
const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction
);

타이머를 생성하는 함수입니다.
pcTimerName : 타이머의 이름이고 디버깅을 위해 사용되며, 동작에는 영향을 미치지 않습니다.
xTimerPeriodInTicks : 타이머의 주기를 설정합니다.
uxAutoReload : 타이머가 자동으로 재시작될지를 정합니다.
(pdTrue : 자동으로 반복 실행(Periodic Timer), pdFalse : 한 번만 실(One-shot Timer)
pvTimerID : 타이머에서 식별자로 사용될수있고 vTimerSetTimerID를 통해 식별자를 새로운 값으로 업데이트할 수 있습니다.
pxCallbackFunction : 타이머가 만료됐을 때 호출되는 콜백함수의 포인터입니다.


*xTimerStart함수
BaseType_t xTimerStart(
TimerHandle_t xTimer,
TickType_t xTicksToWait
);

xTimer : 시작하려는 타이머의 핸들러입니다.
xTicksToWait : 타이머를 큐에 넣기 위해 대기하는 시간(틱) 입니다. 보통은 0으로 설정해서 대기하지 않고 바로 큐에 넣습니다.
타이머를 Create하고나서 타이머를 동작시키려면 Start함수를 호출해줘야합니다.


두개의 함수를 이용해서 타이머 동작시켜보겠습니다. timers.h를 include 해줘야합니다.

#include <stdio.h>
#include "cmsis_os.h"
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

TimerHandle_t xTimer;

// 타이머 콜백 함수
void vTimerCallback(TimerHandle_t xTimer) {
    printf("Hello\n");
}

void myTask()
{
    // 타이머 생성
    xTimer = xTimerCreate(
        "Timer1",                // 타이머 이름
        pdMS_TO_TICKS(1000),         // 타이머 주기 (1000ms)
        pdTRUE,                     // 자동 재시작 (pdTRUE: 반복, pdFALSE: 1회)
        NULL,                  // 타이머 ID
        vTimerCallback              // 타이머 콜백 함수
    );
    // 타이머 생성 확인
    if (xTimer == NULL) {
        // 타이머 생성 실패 처리
        printf("Failed to create timer!\r\n");
        while (1);
    }
    // 타이머 시작
    if (xTimerStart(xTimer, 0) != pdPASS) {
        // 타이머 시작 실패 처리
        printf("Failed to start timer!\r\n");
        while (1);
    }
}



*xTimerStop함수
BaseType_t xTimerStop(
TimerHandle_t xTimer,
TickType_t xTicksToWait
)
;

xTimer : 시작하려는 타이머의 핸들러입니다.
xTicksToWait : 타이머를 큐에 넣기 위해 대기하는 시간(틱) 입니다. 보통은 0으로 설정해서 대기하지 않고 바로 큐에 넣습니다.
타이머가 실행중인경우 멈춥니다.



1개의 LED가 1초간격으로 점멸하고 총 5번 점멸하면 타이머가 끝나는 코드입니다.

#include <stdio.h>
#include "cmsis_os.h"
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"

TimerHandle_t xTimer;
uint8_t ledState = 1;
uint8_t ledCount = 10;

typedef struct {
    GPIO_TypeDef* GPIO_Port;
    uint16_t GPIO_Pin;
} LED_Params;

// 타이머 콜백 함수
void vTimerCallback(TimerHandle_t xTimer) {
    LED_Params *ledInfo = (LED_Params *)pvTimerGetTimerID(xTimer);
    if(ledState)
    {
      HAL_GPIO_WritePin(ledInfo->GPIO_Port, ledInfo->GPIO_Pin, GPIO_PIN_SET);
    }
    else
    {
      HAL_GPIO_WritePin(ledInfo->GPIO_Port, ledInfo->GPIO_Pin, GPIO_PIN_RESET);
    }
    ledState = !ledState;
    ledCount--;
    if(ledCount==0)
    {
      xTimerStop(xTimer,0);
    }
}

void myTask()
{
    static LED_Params led1 = {LED1_GPIO_Port, LED1_Pin};

    // 타이머 생성
    xTimer = xTimerCreate(
        "Timer1",                // 타이머 이름
        pdMS_TO_TICKS(1000),         // 타이머 주기 (1000ms)
        pdTRUE,                     // 자동 재시작 (pdTRUE: 반복, pdFALSE: 1회)
        &led1,                       // 타이머 ID
        vTimerCallback              // 타이머 콜백 함수
    );

    // 타이머 생성 확인
    if (xTimer == NULL) {
        // 타이머 생성 실패 처리
        printf("Failed to create timer!\r\n");
        while (1);
    }

    // 타이머 시작
    if (xTimerStart(xTimer, 0) != pdPASS) {
        // 타이머 시작 실패 처리
        printf("Failed to start timer!\r\n");
        while (1);
    }
}

pvTimerID로 LED_Params 구조체를 넘겼습니다. 그리고 타이머함수 안에서 pvTimerGetTimerID를 통해서 ID를 받았습니다. 받은 ledInfo로 led를 on/off하다가 count가 0이되면 timer가 Stop합니다.


소스코드(Commits: Timer) 
https://github.com/yhunterr/STM32_RTOS_STUDY/commits/main/