본문 바로가기
-----ETC-----/C++ 임베디드 시스템 프로그래밍 시리즈

[C++ 임베디드 시스템 프로그래밍 시리즈] Day 25: 실시간 운영 체제 (RTOS) 개요

by cogito21_cpp 2024. 8. 1.
반응형

RTOS의 개요

RTOS(Real-Time Operating System)는 실시간 응용 프로그램의 요구 사항을 충족하기 위해 설계된 운영 체제입니다. RTOS는 일정한 시간 내에 작업을 수행할 수 있도록 보장하며, 임베디드 시스템에서 주로 사용됩니다. 오늘은 RTOS의 기본 개념과 사용 방법을 학습하고, FreeRTOS를 사용하여 멀티태스킹 시스템을 구현하는 방법을 살펴보겠습니다.

1. RTOS의 기본 개념

RTOS는 다음과 같은 특징을 가집니다:

  • 실시간 성능: 정해진 시간 내에 작업을 완료할 수 있도록 보장
  • 멀티태스킹: 여러 작업을 동시에 실행
  • 우선순위 스케줄링: 우선순위에 따라 작업을 스케줄링
  • 자원 관리: 메모리, CPU 등 시스템 자원을 효율적으로 관리

2. FreeRTOS 소개

FreeRTOS는 오픈 소스 실시간 운영 체제로, 다양한 마이크로컨트롤러에서 사용될 수 있습니다. FreeRTOS는 작은 메모리 풋프린트와 유연한 스케줄링 기능을 제공하여 임베디드 시스템에서 널리 사용됩니다.

3. FreeRTOS 설정

FreeRTOS를 사용하려면 Arduino IDE에서 FreeRTOS 라이브러리를 설치해야 합니다.

 

FreeRTOS 라이브러리 설치

  1. Arduino IDE 라이브러리 매니저 열기:
    • Sketch -> Include Library -> Manage Libraries...
  2. 라이브러리 검색 및 설치:
    • 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의 다양한 기능을 활용하여 멀티태스킹 시스템을 더욱 효율적으로 구현하는 방법을 학습하겠습니다.

반응형