RTOS의 개요
RTOS(Real-Time Operating System)는 실시간 응용 프로그램의 요구 사항을 충족하기 위해 설계된 운영 체제입니다. RTOS는 일정한 시간 내에 작업을 수행할 수 있도록 보장하며, 임베디드 시스템에서 주로 사용됩니다. 오늘은 RTOS의 기본 개념과 사용 방법을 학습하고, FreeRTOS를 사용하여 멀티태스킹 시스템을 구현하는 방법을 살펴보겠습니다.
1. RTOS의 기본 개념
RTOS는 다음과 같은 특징을 가집니다:
- 실시간 성능: 정해진 시간 내에 작업을 완료할 수 있도록 보장
- 멀티태스킹: 여러 작업을 동시에 실행
- 우선순위 스케줄링: 우선순위에 따라 작업을 스케줄링
- 자원 관리: 메모리, CPU 등 시스템 자원을 효율적으로 관리
2. FreeRTOS 소개
FreeRTOS는 오픈 소스 실시간 운영 체제로, 다양한 마이크로컨트롤러에서 사용될 수 있습니다. FreeRTOS는 작은 메모리 풋프린트와 유연한 스케줄링 기능을 제공하여 임베디드 시스템에서 널리 사용됩니다.
3. FreeRTOS 설정
FreeRTOS를 사용하려면 Arduino IDE에서 FreeRTOS 라이브러리를 설치해야 합니다.
FreeRTOS 라이브러리 설치
- Arduino IDE 라이브러리 매니저 열기:
Sketch
->Include Library
->Manage Libraries...
- 라이브러리 검색 및 설치:
FreeRTOS
를 검색하고,FreeRTOS
라이브러리를 설치합니다.
4. FreeRTOS 기본 예제
다음 예제는 FreeRTOS를 사용하여 두 개의 태스크를 실행하는 방법을 보여줍니다.
예제: FreeRTOS를 사용한 멀티태스킹
#include <Arduino_FreeRTOS.h>
void TaskBlink(void *pvParameters);
void TaskPrint(void *pvParameters);
const int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
// 태스크 생성
xTaskCreate(TaskBlink, "Blink", 128, NULL, 1, NULL);
xTaskCreate(TaskPrint, "Print", 128, NULL, 1, NULL);
// 스케줄러 시작
vTaskStartScheduler();
}
void loop() {
// 메인 루프는 비워둠
}
void TaskBlink(void *pvParameters) {
(void) pvParameters;
for (;;) {
digitalWrite(ledPin, HIGH);
vTaskDelay(500 / portTICK_PERIOD_MS);
digitalWrite(ledPin, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
void TaskPrint(void *pvParameters) {
(void) pvParameters;
for (;;) {
Serial.println("Hello from TaskPrint");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
위 코드에서는 두 개의 태스크(TaskBlink와 TaskPrint)를 생성하여 실행합니다. TaskBlink 태스크는 LED를 깜빡이고, TaskPrint 태스크는 시리얼 모니터에 메시지를 출력합니다. FreeRTOS 스케줄러는 두 태스크를 적절히 스케줄링하여 동시에 실행되도록 합니다.
5. FreeRTOS를 사용한 스마트 홈 시스템 구현
FreeRTOS를 사용하여 스마트 홈 시스템에서 센서 데이터를 주기적으로 수집하고, 액추에이터를 제어하는 태스크를 구현해보겠습니다.
예제: FreeRTOS를 사용한 스마트 홈 시스템
#include <Arduino_FreeRTOS.h>
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
// Wi-Fi 설정
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
// DHT 설정
#define DHTPIN 2 // DHT22 데이터 핀 (GPIO 2)
#define DHTTYPE DHT22 // DHT22 센서 타입
DHT dht(DHTPIN, DHTTYPE);
// 핀 설정
const int fanPin = 13; // 팬 제어 핀 (GPIO 13)
float temperatureThreshold = 30.0;
float currentTemperature = 0.0;
ESP8266WebServer server(80); // 웹 서버 포트 설정
void setup() {
Serial.begin(115200);
setupWiFi();
dht.begin();
pinMode(fanPin, OUTPUT);
// 웹 서버 핸들러 설정
server.on("/", handleRoot);
server.on("/setThreshold", handleSetThreshold);
server.begin(); // 웹 서버 시작
Serial.println("HTTP server started");
// 태스크 생성
xTaskCreate(TaskSensorRead, "SensorRead", 128, NULL, 1, NULL);
xTaskCreate(TaskControl, "Control", 128, NULL, 1, NULL);
// 스케줄러 시작
vTaskStartScheduler();
}
void loop() {
server.handleClient(); // 클라이언트 요청 처리
}
void TaskSensorRead(void *pvParameters) {
(void) pvParameters;
for (;;) {
currentTemperature = dht.readTemperature();
if (isnan(currentTemperature)) {
Serial.println("Failed to read from DHT sensor!");
}
vTaskDelay(2000 / portTICK_PERIOD_MS); // 2초마다 센서 데이터 읽기
}
}
void TaskControl(void *pvParameters) {
(void) pvParameters;
for (;;) {
if (currentTemperature > temperatureThreshold) {
digitalWrite(fanPin, HIGH); // 팬 켜기
} else {
digitalWrite(fanPin, LOW); // 팬 끄기
}
vTaskDelay(500 / portTICK_PERIOD_MS); // 0.5초마다 제어
}
}
void handleRoot() {
String html = "<html><body>";
html += "<h1>Smart Home System</h1>";
html += "<p>Temperature: " + String(currentTemperature) + " *C</p>";
html += "<p>Current Threshold: " + String(temperatureThreshold) + " *C</p>";
html += "<form action=\"/setThreshold\" method=\"POST\">";
html += "Set Temperature Threshold: <input type=\"text\" name=\"threshold\">";
html += "<input type=\"submit\" value=\"Set\">";
html += "</form>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleSetThreshold() {
if (server.hasArg("threshold")) {
temperatureThreshold = server.arg("threshold").toFloat();
server.sendHeader("Location", "/");
server.send(303);
} else {
server.send(400, "text/plain", "Bad Request");
}
}
void setupWiFi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); // IP 주소 출력
}
위 코드에서는 FreeRTOS를 사용하여 센서 데이터를 주기적으로 읽는 태스크(TaskSensorRead)와 팬을 제어하는 태스크(TaskControl)를 생성하여 실행합니다. 두 태스크는 FreeRTOS 스케줄러에 의해 동시에 실행되며, 웹 서버를 통해 온도 임계값을 설정할 수 있습니다.
마무리
오늘은 RTOS의 기본 개념과 FreeRTOS를 사용하여 멀티태스킹 시스템을 구현하는 방법을 학습했습니다. FreeRTOS를 사용하여 스마트 홈 시스템에서 센서 데이터를 수집하고 액추에이터를 제어하는 예제를 통해 실시간 운영 체제의 기본 개념과 활용 방법을 익혔습니다. 다음 단계에서는 FreeRTOS를 사용한 멀티태스킹 시스템을 더 깊이 있게 다루겠습니다.
질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요.
Day 26 예고
다음 날은 "FreeRTOS를 이용한 멀티태스킹"에 대해 다룰 것입니다. FreeRTOS의 다양한 기능을 활용하여 멀티태스킹 시스템을 더욱 효율적으로 구현하는 방법을 학습하겠습니다.
'-----ETC----- > C++ 임베디드 시스템 프로그래밍 시리즈' 카테고리의 다른 글
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 27: 임베디드 시스템의 메모리 최적화 (0) | 2024.08.01 |
---|---|
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 28: 저전력 설계 기법 (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 26: FreeRTOS를 이용한 멀티태스킹 (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 23: 프로젝트: 스마트 홈 시스템 구축 (2) (0) | 2024.08.01 |
[C++ 임베디드 시스템 프로그래밍 시리즈] Day 24: 프로젝트: 스마트 홈 시스템 구축 (3) (0) | 2024.08.01 |