안녕하세요. 오늘은 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/
'STM32 > STM32_RTOS' 카테고리의 다른 글
STM32 RTOS 알아보기 5편(portYIELD_FROM_ISR) (0) | 2025.02.01 |
---|---|
STM32 RTOS 알아보기 3편(xQueueSendFromISR,xQueueReceiveFromISR) (0) | 2024.10.04 |
STM32 RTOS 알아보기 2편(xQueueCreate,xQueueSend,xQueueReceive) (0) | 2024.08.18 |
STM32 RTOS 알아보기 1편(xTaskCreate, vTaskDelay, vTaskDelayUntil) (0) | 2024.08.11 |
FreeRTOS-undefined reference to `vTaskList'에러 (0) | 2023.04.02 |