FreeRTOS 멀티태스킹 개요
FreeRTOS는 실시간 운영 체제(RTOS)로, 임베디드 시스템에서 멀티태스킹을 구현할 수 있는 기능을 제공합니다. 오늘은 FreeRTOS의 다양한 기능을 활용하여 멀티태스킹 시스템을 더욱 효율적으로 구현하는 방법을 학습하겠습니다.
1. FreeRTOS의 주요 기능
- 태스크 관리: 여러 개의 태스크를 생성하고 스케줄링
- 태스크 간 통신: 큐(Queue), 세마포어(Semaphore), 뮤텍스(Mutex)를 사용하여 태스크 간 데이터를 주고받고 동기화
- 타이머: 주기적으로 실행되는 타이머 기능
2. 태스크 간 통신
FreeRTOS에서 태스크 간 통신을 위해 큐(Queue)를 사용할 수 있습니다. 큐는 데이터를 FIFO(First In, First Out) 방식으로 저장하여, 한 태스크에서 데이터를 큐에 넣고, 다른 태스크에서 데이터를 큐에서 꺼내 사용할 수 있습니다.
예제: 큐를 사용한 태스크 간 통신
다음 예제는 두 개의 태스크 간에 큐를 사용하여 데이터를 주고받는 방법을 보여줍니다.
#include <Arduino_FreeRTOS.h>
#include <queue.h>
QueueHandle_t xQueue;
void TaskSender(void *pvParameters);
void TaskReceiver(void *pvParameters);
void setup() {
Serial.begin(115200);
// 큐 생성
xQueue = xQueueCreate(10, sizeof(int));
// 태스크 생성
xTaskCreate(TaskSender, "Sender", 128, NULL, 1, NULL);
xTaskCreate(TaskReceiver, "Receiver", 128, NULL, 1, NULL);
// 스케줄러 시작
vTaskStartScheduler();
}
void loop() {
// 메인 루프는 비워둠
}
void TaskSender(void *pvParameters) {
(void) pvParameters;
int valueToSend = 0;
for (;;) {
valueToSend++;
xQueueSend(xQueue, &valueToSend, portMAX_DELAY);
Serial.print("Sent: ");
Serial.println(valueToSend);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void TaskReceiver(void *pvParameters) {
(void) pvParameters;
int receivedValue = 0;
for (;;) {
if (xQueueReceive(xQueue, &receivedValue, portMAX_DELAY)) {
Serial.print("Received: ");
Serial.println(receivedValue);
}
}
}
위 코드에서는 두 개의 태스크(TaskSender와 TaskReceiver)를 생성하여 실행합니다. TaskSender 태스크는 값을 증가시키면서 큐에 데이터를 넣고, TaskReceiver 태스크는 큐에서 데이터를 꺼내어 시리얼 모니터에 출력합니다.
3. 세마포어와 뮤텍스
FreeRTOS에서 세마포어와 뮤텍스를 사용하여 태스크 간의 동기화를 구현할 수 있습니다. 세마포어는 리소스의 접근을 제어하고, 뮤텍스는 상호 배제를 보장합니다.
예제: 세마포어를 사용한 동기화
다음 예제는 세마포어를 사용하여 두 개의 태스크 간에 동기화를 구현하는 방법을 보여줍니다.
#include <Arduino_FreeRTOS.h>
#include <semphr.h>
SemaphoreHandle_t xSemaphore;
void Task1(void *pvParameters);
void Task2(void *pvParameters);
void setup() {
Serial.begin(115200);
// 세마포어 생성
xSemaphore = xSemaphoreCreateBinary();
// 태스크 생성
xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL);
xTaskCreate(Task2, "Task2", 128, NULL, 1, NULL);
// 스케줄러 시작
vTaskStartScheduler();
}
void loop() {
// 메인 루프는 비워둠
}
void Task1(void *pvParameters) {
(void) pvParameters;
for (;;) {
Serial.println("Task1 is running");
xSemaphoreGive(xSemaphore); // 세마포어를 놓음
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void Task2(void *pvParameters) {
(void) pvParameters;
for (;;) {
if (xSemaphoreTake(xSemaphore, portMAX_DELAY)) {
Serial.println("Task2 is running");
}
}
}
위 코드에서는 두 개의 태스크(Task1과 Task2)를 생성하여 실행합니다. Task1 태스크는 주기적으로 세마포어를 놓고, Task2 태스크는 세마포어를 얻으면 동작합니다. 이를 통해 두 태스크 간의 동기화를 구현할 수 있습니다.
4. 타이머 사용
FreeRTOS에서 타이머를 사용하여 주기적으로 실행되는 작업을 구현할 수 있습니다.
예제: 타이머를 사용한 주기적 작업
다음 예제는 타이머를 사용하여 주기적으로 LED를 깜빡이는 작업을 구현하는 방법을 보여줍니다.
#include <Arduino_FreeRTOS.h>
#include <timers.h>
const int ledPin = 13; // LED 핀
TimerHandle_t xTimer;
void vTimerCallback(TimerHandle_t xTimer);
void setup() {
pinMode(ledPin, OUTPUT);
// 타이머 생성 (주기: 500ms)
xTimer = xTimerCreate("LEDTimer", pdMS_TO_TICKS(500), pdTRUE, (void *)0, vTimerCallback);
// 타이머 시작
if (xTimerStart(xTimer, 0) != pdPASS) {
Serial.println("Failed to start timer");
}
// 스케줄러 시작
vTaskStartScheduler();
}
void loop() {
// 메인 루프는 비워둠
}
void vTimerCallback(TimerHandle_t xTimer) {
static bool ledState = false;
ledState = !ledState;
digitalWrite(ledPin, ledState ? HIGH : LOW);
}
위 코드에서는 타이머를 생성하여 주기적으로 LED를 깜빡이는 작업을 구현합니다. 타이머는 500ms 주기로 실행되며, LED의 상태를 토글합니다.
마무리
오늘은 FreeRTOS의 다양한 기능을 활용하여 멀티태스킹 시스템을 더욱 효율적으로 구현하는 방법을 학습했습니다. 큐를 사용한 태스크 간 통신, 세마포어를 사용한 동기화, 타이머를 사용한 주기적 작업 예제를 통해 FreeRTOS의 기능을 익혔습니다. 다음 단계에서는 임베디드 시스템의 메모리 최적화에 대해 알아보겠습니다.
질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요.
Day 27 예고
다음 날은 "임베디드 시스템의 메모리 최적화"에 대해 다룰 것입니다. 메모리 사용을 최적화하여 임베디드 시스템의 성능을 향상시키는 방법을 학습하겠습니다.
'-----ETC----- > C++ 임베디드 시스템 프로그래밍 시리즈' 카테고리의 다른 글
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 28: 저전력 설계 기법 (0) | 2024.08.01 |
---|---|
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 25: 실시간 운영 체제 (RTOS) 개요 (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 23: 프로젝트: 스마트 홈 시스템 구축 (2) (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 24: 프로젝트: 스마트 홈 시스템 구축 (3) (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍] Day 21: MQTT 프로토콜 (0) | 2024.08.01 |