미션컴퓨터 3가지 RTOS

미션 컴퓨터와 임베디드 시스템에서 널리 사용되는 4개의 주요 RTOS (Real-Time Operating System)에 대해 알아보겠습니다. 각 RTOS의 특징, 개발자 관점에서의 장단점, Hello World 예제 코드, 그리고 실제 산업 적용 사례를 살펴봄으로써 개발자들이 프로젝트에 가장 적합한 RTOS를 선택하고 활용할 수 있습니다.

1. VxWorks

개요

  • 개발사: Wind River Systems
  • 주요 특징:
    • 마이크로초 단위의 정밀한 태스크 스케줄링을 제공하는 고성능 실시간 커널
    • DO-178B, IEC 61508 등 다양한 안전 인증 획득으로 입증된 안정성
    • Board Support Package (BSP)를 통한 하드웨어 추상화로 높은 확장성 제공
    • POSIX API 지원으로 이식성 향상 및 개발 편의성 제공

장단점

  • 장점:
    • 풍부한 드라이버와 미들웨어 라이브러리로 개발 시간 단축
    • Wind River Workbench IDE를 통한 강력한 개발 및 디버깅 환경 제공
    • 실시간 커널 가시화 도구로 성능 최적화 용이
  • 단점:
    • 상용 라이선스로 인한 높은 초기 비용 부담
    • 복잡한 시스템으로 인한 다소 가파른 학습 곡선

Hello World

#include <vxWorks.h>
#include <taskLib.h>
#include <stdio.h>

#define TASK_PRIORITY      100
#define TASK_STACK_SIZE    20000

void helloTask(void)
{
    while(1) {
        printf("Hello, VxWorks World!\n");
        taskDelay(sysClkRateGet() * 2);  // 2초 대기
    }
}

int start(void)
{
    if (taskSpawn("tHello", TASK_PRIORITY, 0, TASK_STACK_SIZE,
                  (FUNCPTR)helloTask, 0,0,0,0,0,0,0,0,0,0) == ERROR)
    {
        printf("Failed to create task\n");
        return ERROR;
    }
    return OK;
}

이 예제에서는 taskSpawn()을 사용하여 새 태스크를 생성하고, taskDelay()로 주기적인 실행을 구현합니다. sysClkRateGet()은 시스템 틱 레이트를 반환하여 이식성 있는 지연을 구현할 수 있게 해줍니다.

사례

  1. NASA 화성 탐사 로버

    • 프로젝트: Mars Exploration Rovers (Spirit and Opportunity)
    • 적용: 로버의 메인 컴퓨터 시스템에서 미션 크리티컬한 작업 관리
    • 이점: 극한의 환경에서도 안정적인 운영과 실시간 응답성 제공
  2. 보잉 787 드림라이너

    • 적용: 항공기의 비행 제어 시스템과 기타 중요 시스템
    • 이점: DO-178B 인증을 통한 높은 안전성과 신뢰성 보장
  3. BMW iDrive 시스템

    • 적용: 차량의 인포테인먼트 및 내비게이션 시스템
    • 이점: 빠른 부팅 시간과 안정적인 성능으로 사용자 경험 향상

2. QNX

개요

  • 개발사: BlackBerry Limited (구 QNX Software Systems)
  • 주요 특징:
    • 마이크로커널 아키텍처로 높은 안정성과 모듈성 제공
    • 우선순위 상속 프로토콜을 통한 우수한 실시간 응답성
    • Transparent Distributed Processing (TDP) 지원으로 분산 시스템 구축 용이
    • 저널링 및 암호화를 지원하는 고급 파일 시스템 제공

장단점

  • 장점:
    • POSIX 호환성으로 인한 높은 이식성과 기존 코드 재사용 가능
    • QNX Momentics IDE를 통한 강력한 개발 및 디버깅 도구 제공
    • 실시간 시스템 분석 도구로 성능 최적화 및 문제 해결 용이
  • 단점:
    • QNX 고유 API 학습에 추가 시간 투자 필요
    • 상용 라이선스 정책으로 인한 비용 고려 필요

Hello World

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* helloThread(void* arg)
{
    while(1) {
        printf("Hello, QNX World!\n");
        sleep(2);  // 2초 대기
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t thread;
    int result;

    result = pthread_create(&thread, NULL, helloThread, NULL);
    if (result != 0) {
        perror("pthread_create");
        return 1;
    }

    pthread_join(thread, NULL);
    return 0;
}

QNX는 POSIX 스레드를 사용하여 태스크를 생성합니다. pthread_create()로 새 스레드를 만들고, pthread_join()으로 스레드 종료를 기다립니다.

사례

  1. 자율주행 차량 시스템

    • 적용: 여러 자동차 제조사의 자율주행 및 ADAS(Advanced Driver Assistance Systems) 시스템
    • 이점: 고도의 안정성과 실시간 성능으로 안전 크리티컬한 기능 지원
  2. 의료기기

    • 적용: MRI 스캐너, 혈액 분석기 등 다양한 의료 장비
    • 이점: FDA 인증을 용이하게 하는 신뢰성과 실시간 데이터 처리 능력 제공
  3. 발전소 제어 시스템

    • 적용: 원자력 및 화력 발전소의 모니터링 및 제어 시스템
    • 이점: 고도의 신뢰성과 실시간 성능으로 중요한 프로세스를 안전하게 관리

3. RTEMS (Real-Time Executive for Multiprocessor Systems)

개요

  • 개발사: 오픈 소스 커뮤니티
  • 주요 특징:
    • GNU GPL 라이선스로 제공되는 오픈 소스 RTOS
    • 다양한 프로세서 아키텍처 지원으로 높은 이식성
    • 모듈화된 설계로 높은 커스터마이징 가능성
    • POSIX API 지원으로 표준 준수 및 이식성 향상

장단점

  • 장점:
    • 무료 오픈 소스로 비용 부담 없이 사용 가능
    • 활발한 커뮤니티 지원으로 문제 해결 및 지식 공유 용이
    • 높은 커스터마이징 가능성으로 특수한 요구사항 충족 가능
  • 단점:
    • 상용 RTOS에 비해 기술 지원이 제한적일 수 있음
    • 일부 고급 기능의 경우 직접 구현이 필요할 수 있음

Hello World

#include <rtems.h>
#include <stdio.h>

rtems_task Hello_world_task(rtems_task_argument unused)
{
    while(1) {
        printf("Hello, RTEMS World!\n");
        rtems_task_wake_after(rtems_clock_get_ticks_per_second() * 2);
    }
    rtems_task_delete(RTEMS_SELF);
}

#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT

#include <rtems/confdefs.h>

rtems_task Init(rtems_task_argument argument)
{
    rtems_status_code status;
    rtems_id task_id;

    status = rtems_task_create(rtems_build_name('H', 'E', 'L', 'O'),
                               1, RTEMS_MINIMUM_STACK_SIZE,
                               RTEMS_DEFAULT_MODES,
                               RTEMS_DEFAULT_ATTRIBUTES, &task_id);

    if (status != RTEMS_SUCCESSFUL) {
        printf("rtems_task_create failed with status: %d\n", status);
        exit(1);
    }

    status = rtems_task_start(task_id, Hello_world_task, 0);

    if (status != RTEMS_SUCCESSFUL) {
        printf("rtems_task_start failed with status: %d\n", status);
        exit(1);
    }

    status = rtems_task_delete(RTEMS_SELF);
}

RTEMS는 설정 매크로를 사용하여 시스템 리소스를 정의합니다. rtems_task_create()rtems_task_start()를 사용하여 태스크를 생성하고 시작합니다.

사례

  1. 유럽우주국(ESA) 위성 시스템

    • 프로젝트: Herschel Space Observatory
    • 적용: 위성의 온보드 컴퓨터 시스템
    • 이점: 오픈 소스의 특성을 활용한 높은 커스터마이징 가능성과 비용 효율성
  2. 항공 교통 관제 시스템

    • 적용: 일부 국가의 항공 교통 관제 시스템
    • 이점: 실시간 성능과 높은 신뢰성으로 안전한 항공 교통 관리 지원
  3. 입자 가속기 제어

    • 프로젝트: 유럽입자물리연구소(CERN)의 대형 강입자 충돌기(LHC)
    • 적용: 일부 제어 및 데이터 수집 시스템
    • 이점: 정밀한 타이밍 제어와 고성능 데이터 처리 능력 제공

4. Integrity RTOS

개요

  • 개발사: Green Hills Software
  • 주요 특징:
    • 시간 및 공간 파티셔닝을 통한 고수준의 격리 제공
    • DO-178C Level A 및 Common Criteria EAL 6+ 인증 획득
    • 결정적 스케줄링과 낮은 지터로 우수한 실시간 성능 제공
    • 고도의 안전성과 보안성이 요구되는 시스템에 적합

장단점

  • 장점:
    • MULTI IDE를 통한 강력한 개발 및 디버깅 환경 제공
    • 고도의 안전성과 보안성이 요구되는 프로젝트에 이상적
    • 고급 시스템 분석 및 최적화 도구로 성능 튜닝 용이
  • 단점:
    • 높은 라이선스 비용으로 초기 투자 부담 있음
    • 특화된 API 학습에 추가 시간 투자 필요

Hello World

#include <stdio.h>
#include <integrity.h>

void HelloTask(void)
{
    while(1) {
        printf("Hello, Integrity World!\n");
        PosTaskDelay(2000);  // 2000ms 대기
    }
}

int main(void)
{
    TaskId taskId;
    taskId = PosTaskCreate(HelloTask, 10, 0, 0, "HelloTask");
    if (taskId == 0) {
        printf("Failed to create task\n");
        return 1;
    }
    PosTaskActivate(taskId);
    return 0;
}

5. MDSTech NEOS

개요

  • 개발사: MDSTech

Hello World

#include <neos.h>
#include <stdio.h>
#define TASK1_PRIORITY 10
#define TASK2_PRIORITY 11
#define STACK_SIZE 1024
neos_task_t task1, task2;
neos_mutex_t mutex;
neos_semaphore_t semaphore;
void task1_function(void *arg)
{
    while (1) {
        neos_mutex_lock(&mutex);
        printf("Task 1 is running\n");
        neos_mutex_unlock(&mutex);

        neos_semaphore_give(&semaphore);
        neos_task_delay(100);  // 100ms 딜레이
    }
}
void task2_function(void *arg)
{
    while (1) {
        neos_semaphore_take(&semaphore, NEOS_WAIT_FOREVER);

        neos_mutex_lock(&mutex);
        printf("Task 2 is running\n");
        neos_mutex_unlock(&mutex);

        neos_task_delay(50);  // 50ms 딜레이
    }
}
int main()
{
    neos_init();  // NEOS 초기화

    // 뮤텍스 생성
    neos_mutex_create(&mutex);

    // 세마포어 생성 (초기 값 0)
    neos_semaphore_create(&semaphore, 0);

    // 태스크 생성
    neos_task_create(&task1, "Task1", task1_function, NULL, TASK1_PRIORITY, STACK_SIZE);
    neos_task_create(&task2, "Task2", task2_function, NULL, TASK2_PRIORITY, STACK_SIZE);

    // 스케줄러 시작
    neos_start_scheduler();

    // 여기에 도달하면 안 됨
    return 0;
}