# Xenomai API 개요

Xenomai는 실시간 애플리케이션의 개발을 용이하게 하는 다양한 API를 제공한다. 이 섹션에서는 Xenomai의 주요 API들을 개요하고, 각각의 특징과 사용 방법을 간단히 소개한다.

### 핵심 Xenomai API

Xenomai는 주로 여러 실시간 운영 환경을 제공하는데, 아래와 같은 주요 API 세트를 갖추고 있다.

#### POSIX API

Xenomai는 POSIX 규격의 실시간 확장을 제공하여, 기존 POSIX 호환 코드의 리얼타임성을 보장한다. 이는 사용자가 리눅스와 유사한 방식으로 쓰레드, 뮤텍스, 조건 변수 등을 사용해서 실시간 애플리케이션을 개발할 수 있게 해준다.

* **pthread\_create**: 새로운 POSIX 쓰레드를 생성한다.
* **pthread\_mutex\_lock**: 뮤텍스를 잠급니다.
* **pthread\_cond\_wait**: 조건 변수를 기다린다.

#### Native API

Xenomai Native API는 Xenomai의 최대 성능을 활용할 수 있는 API이다. 이는 Xenomai의 기본 기능을 직접 접근할 수 있는 방법을 제공한다.

* **rt\_task\_create**: 새로운 실시간 태스크를 생성한다.
* **rt\_task\_start**: 실시간 태스크를 시작한다.
* **rt\_task\_delete**: 실시간 태스크를 삭제한다.

#### Alchemy API

Alchemy는 고급 실시간 기능을 제공하는 API 패키지로, Xenomai 사용자들을 위한 고성능 실시간 애플리케이션 개발에 최적화된 API이다.

* **rt\_mutex\_create**: 실시간 뮤텍스를 생성한다.
* **rt\_sem\_broadcast**: 세마포를 브로드캐스트 한다.
* **rt\_queue\_create**: 실시간 큐를 생성한다.

### API 사용 예제

#### POSIX API 사용 예제

```c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

void* thread_function(void* arg) {
    printf("Hello from POSIX thread!\n");
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);
    return 0;
}
```

#### Native API 사용 예제

```c
#include <native/task.h>
#include <rtdk.h>

void task_function(void *arg) {
    rt_printf("Hello from Native API task!\n");
}

int main() {
    RT_TASK task;
    rt_task_create(&task, "Task", 0, 50, 0);
    rt_task_start(&task, &task_function, NULL);
    rt_task_delete(&task);
    return 0;
}
```

#### Alchemy API 사용 예제

```c
#include <alchemy/task.h>
#include <alchemy/timer.h>
#include <alchemy/sem.h>
#include <rtdk.h>

void task_function(void *arg) {
    RT_SEM *sem = (RT_SEM *)arg;
    rt_sem_p(sem, TM_INFINITE);
    rt_printf("Semaphore acquired, task running!\n");
}

int main() {
    RT_TASK task;
    RT_SEM sem;

    rt_sem_create(&sem, "MySemaphore", 0, S_PRIO);
    rt_task_create(&task, "Task", 0, 50, 0);
    rt_task_start(&task, &task_function, &sem);
    
    rt_timer_spin(1000000000); // Wait for 1 second
    rt_sem_broadcast(&sem);

    rt_task_delete(&task);
    rt_sem_delete(&sem);
    return 0;
}
```

### Xenomai API 심화

이제 간단한 예제를 실습해봤으니, 실시간 시스템에서 자주 사용하는 몇 가지 고급 기능과 그 활용 방법에 대해 살펴보겠다.

#### 실시간 타이머

실시간 애플리케이션에서 시간당 작업 주기를 관리하는 것은 매우 중요하다. Xenomai는 이를 위해 고성능 타이머를 제공한다.

**Alchemy 타이머 API**

* **rt\_timer\_ns2ticks**: 나노초 단위의 시간을 타이머 틱(ticks) 단위로 변환한다.
* **rt\_timer\_read**: 현재 타이머 값을 읽어온다.

**실시간 타이머 사용 예제**

```c
#include <alchemy/task.h>
#include <alchemy/timer.h>
#include <rtdk.h>

void task_function(void *arg) {
    RTIME start_time = rt_timer_read();

    // 1초 대기
    rt_task_sleep(1000000000); // 1 second

    RTIME end_time = rt_timer_read();
    rt_printf("Elapsed time: %llu ns\n", end_time - start_time);
}

int main() {
    RT_TASK task;
    rt_task_create(&task, "TimeTask", 0, 50, 0);
    rt_task_start(&task, &task_function, NULL);
    
    rt_task_join(&task);
    rt_task_delete(&task);
    return 0;
}
```

#### 이벤트

실시간 시스템에서는 여러 이벤트를 감지하고 이에 대응하는 것이 중요하다. Xenomai는 효과적인 이벤트 관리 기능을 제공한다.

**Native 이벤트 API**

* **rt\_event\_create**: 새로운 이벤트 컨트롤 블록을 생성한다.
* **rt\_event\_signal**: 특정 이벤트를 신호한다.
* **rt\_event\_wait**: 이벤트가 발생할 때까지 기다린다.

**이벤트 사용 예제**

```c
#include <native/task.h>
#include <native/event.h>
#include <rtdk.h>

#define EVENT_MASK 1

void event_handler(void *arg) {
    RT_EVENT *event = (RT_EVENT *)arg;
    rt_event_wait(event, EVENT_MASK, EV_ANY, TM_INFINITE, NULL);
    rt_printf("Event received!\n");
}

int main() {
    RT_TASK task;
    RT_EVENT event;
    
    rt_event_create(&event, "MyEvent", 0, EV_PRIO);
    
    rt_task_create(&task, "EventTask", 0, 50, 0);
    rt_task_start(&task, &event_handler, &event);
    
    rt_timer_spin(1000000000); // 1 second delay
    rt_event_signal(&event, EVENT_MASK);
    
    rt_task_join(&task);
    rt_task_delete(&task);
    rt_event_delete(&event);
    return 0;
}
```

### 인터럽트 관리

실시간 시스템에서는 하드웨어 및 소프트웨어 인터럽트를 효율적으로 관리하는 것이 중요하다.

#### Native 인터럽트 API

* **rt\_intr\_create**: 새로운 인터럽트 객체를 생성한다.
* **rt\_intr\_enable**: 특정 인터럽트 라인을 활성화한다.
* **rt\_intr\_wait**: 인터럽트가 발생할 때까지 기다린다.

**인터럽트 사용 예제**

```c
#include <native/intr.h>
#include <rtdk.h>

#define IRQ_NUMBER 10

void interrupt_handler(void *arg) {
    RT_INTR *intr = (RT_INTR *)arg;
    unsigned long dummy;
    
    rt_intr_wait(intr, TM_INFINITE, &dummy);
    rt_printf("Interrupt serviced!\n");
}

int main() {
    RT_INTR intr;
    rt_intr_create(&intr, "MyInterrupt", IRQ_NUMBER, I_PRIO);
    
    rt_intr_enable(&intr);
    
    while (1) {
        rt_timer_spin(1000000000); // Periodically trigger interrupt
        rt_intr_wait(&intr, TM_INFINITE, NULL);
        rtc_task_start(&intr, &interrupt_handler, &intr);
    }
    
    rt_intr_delete(&intr);
    return 0;
}
```

이렇게 다양한 Xenomai API를 통해 실시간 시스템을 효과적으로 관리할 수 있다. 각 기능을 적절히 활용하여 애플리케이션의 성능과 실시간성을 극대화 할 수 있다.
