# Xenomai의 Alchemy API: 상세 개요

### Alchemy API 소개

Alchemy는 Xenomai에서 실시간 애플리케이션 개발을 위해 제공되는 고수준의 API이다. 이 API는 기존의 POSIX API와 유사한 인터페이스를 제공하여 개발자가 익숙한 방식으로 실시간 기능을 구현할 수 있도록 돕는다. Alchemy API는 주로 스레드 관리, 타이머, 메시지 큐, 세마포어 등의 기능을 포함하며, 이러한 기능들을 통해 실시간 애플리케이션을 더 간편하게 개발할 수 있다.

### Alchemy API의 주요 구성 요소

#### 스레드 관리

Alchemy API는 스레드 생성을 위한 `rt_task_create` 함수와, 스레드를 시작하는 `rt_task_start` 함수를 제공한다. 이러한 함수들은 스레드를 손쉽게 생성하고, 제어할 수 있도록 돕는다. 스레드 우선순위, 주기, 스택 크기 등을 설정할 수 있으며, 실시간 스케줄링 정책에 따라 스레드를 실행할 수 있다.

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

RT_TASK my_task;

void task_entry(void *arg) {
    // 스레드 메인 로직
}

int main() {
    rt_task_create(&my_task, "MyTask", 0, 50, 0);
    rt_task_start(&my_task, &task_entry, NULL);

    // 샘플 코드가 끝날 때까지 대기
    rt_task_sleep(rt_timer_ns2ticks(1000000000));
    return 0;
}
```

#### 동기화 및 통신

**세마포어**

Alchemy API는 세마포어 기능을 제공하여 다중 스레드 환경에서 자원 접근을 동기화할 수 있다. `rt_sem_create` 함수로 세마포어를 생성하고, `rt_sem_p`와 `rt_sem_v` 함수를 통해 세마포어를 잠그거나 풀 수 있다.

```c
#include <alchemy/sem.h>

RT_SEM my_semaphore;

int main() {
    rt_sem_create(&my_semaphore, "MySemaphore", 1, S_PRIO);

    // 세마포어 잠금
    rt_sem_p(&my_semaphore, TM_INFINITE);

    // 임계 구역

    // 세마포어 풀기
    rt_sem_v(&my_semaphore);

    return 0;
}
```

**메시지 큐**

Alchemy API는 `rt_queue_create` 함수를 통해 메시지 큐를 생성하고, `rt_queue_send`와 `rt_queue_receive`를 통해 메시지를 송수신할 수 있다. 이를 통해 스레드 간의 통신을 쉽게 구현할 수 있다.

```c
#include <alchemy/queue.h>

RT_QUEUE my_queue;

typedef struct {
    int data;
} message_t;

int main() {
    message_t msg;
    msg.data = 42;

    rt_queue_create(&my_queue, "MyQueue", sizeof(message_t) * 10, Q_UNLIMITED, Q_FIFO);

    rt_queue_send(&my_queue, &msg, sizeof(message_t), Q_NORMAL);

    message_t *recv_msg;
    rt_queue_receive(&my_queue, (void**)&recv_msg, TM_INFINITE);
    
    // 수신된 메시지 처리
    printf("Received data: %d\n", recv_msg->data);
    rt_heap_free(&my_queue, recv_msg);

    return 0;
}
```

#### 타이머

Alchemy API는 높은 정밀도의 타이머 기능을 제공한다. `rt_timer_start`와 `rt_timer_stop` 함수를 사용해 타이머를 제어하며, 정해진 시간이 되었을 때 이벤트를 발생시킬 수 있다.

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

void timer_handler() {
    // 타이머가 만료되었을 때의 처리
}

int main() {
    RT_TIMER my_timer;

    rt_timer_create(&my_timer, "MyTimer", &timer_handler, rt_timer_ns2ticks(100000000), 0);

    // 타이머 시작
    rt_timer_start(&my_timer);

    // 프로그램이 종료될 때까지 대기
    rt_task_sleep(rt_timer_ns2ticks(1000000000));

    // 타이머 정지
    rt_timer_stop(&my_timer);

    return 0;
}
```

### Alchemy API의 주요 함수 및 그 사용 예제

#### `rt_task_create`

스레드를 생성하는 함수이다. 다음과 같은 인자를 받아들이다:

* `RT_TASK *task`: 생성된 스레드를 참조할 포인터
* `const char *name`: 스레드의 이름
* `int stacksize`: 스레드의 스택 크기
* `int prio`: 스레드의 우선순위
* `int mode`: 스레드 생성 모드

```c
RT_TASK my_task;
rt_task_create(&my_task, "MyTask", 0, 50, 0);
```

#### `rt_task_start`

생성된 스레드를 시작하는 함수이다. 다음과 같은 인자를 받아들이다:

* `RT_TASK *task`: 시작할 스레드
* `void (*entry)(void *)`: 스레드의 진입점 (함수 포인터)
* `void *arg`: 스레드에 전달할 인자

```c
void task_entry(void *arg) {
    // 스레드 메인 로직
}

rt_task_start(&my_task, &task_entry, NULL);
```

#### `rt_task_sleep`

특정 시간 동안 현재 실행 중인 스레드를 일시 중지하는 함수이다. `rt_timer_ns2ticks` 함수와 함께 사용하면 나노초 단위의 정밀한 대기 시간을 지정할 수 있다.

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

void task_entry(void *arg) {
    // 1초 동안 대기
    rt_task_sleep(rt_timer_ns2ticks(1000000000));

    // 이후 수행할 작업
}

int main() {
    RT_TASK my_task;
    rt_task_create(&my_task, "MyTask", 0, 50, 0);
    rt_task_start(&my_task, &task_entry, NULL);

    return 0;
}
```

#### `rt_sem_create`

세마포어를 생성하는 함수이다. 다음 인자를 받아들이다:

* `RT_SEM *sem`: 생성된 세마포어를 참조할 포인터
* `const char *name`: 세마포어 이름
* `unsigned long icount`: 초기 카운트 값
* `int mode`: 세마포어 생성 모드

```c
RT_SEM my_semaphore;
rt_sem_create(&my_semaphore, "MySemaphore", 1, S_PRIO);
```

#### `rt_sem_p`와 `rt_sem_v`

`rt_sem_p` 함수는 세마포어를 잠그는 함수이며, `rt_sem_v` 함수는 세마포어를 풀어준다. `rt_sem_p`는 지정된 시간 동안 세마포어가 사용 가능해지기를 기다린다.

```c
// 세마포어 잠금
rt_sem_p(&my_semaphore, TM_INFINITE);

// 임계 구역

// 세마포어 풀기
rt_sem_v(&my_semaphore);
```

#### `rt_queue_create`

메시지 큐를 생성하는 함수이다. 다음 인자를 받아들이다:

* `RT_QUEUE *q`: 생성된 메시지 큐를 참조할 포인터
* `const char *name`: 메시지 큐 이름
* `long poolsize`: 큐의 풀 크기 (바이트 단위)
* `long qlimit`: 큐의 최대 메시지 수
* `int mode`: 큐 생성 모드

```c
RT_QUEUE my_queue;
rt_queue_create(&my_queue, "MyQueue", sizeof(message_t) * 10, Q_UNLIMITED, Q_FIFO);
```

#### `rt_queue_send`와 `rt_queue_receive`

`rt_queue_send` 함수는 메시지 큐에 메시지를 보내는 함수이며, `rt_queue_receive` 함수는 메시지 큐로부터 메시지를 읽어오는 함수이다.

```c
message_t msg;
msg.data = 42;

rt_queue_send(&my_queue, &msg, sizeof(message_t), Q_NORMAL);

message_t *recv_msg;
rt_queue_receive(&my_queue, (void**)&recv_msg, TM_INFINITE);

// 수신된 메시지 처리
printf("Received data: %d\n", recv_msg->data);
rt_heap_free(&my_queue, recv_msg);
```

#### `rt_timer_start`와 `rt_timer_stop`

`rt_timer_start` 함수는 타이머를 시작하며, `rt_timer_stop` 함수는 타이머를 중지한다.

```c
RT_TIMER my_timer;

void timer_handler() {
    // 타이머가 만료되었을 때의 처리
}

rt_timer_create(&my_timer, "MyTimer", &timer_handler, rt_timer_ns2ticks(100000000), 0);
rt_timer_start(&my_timer);

// 프로그램이 종료될 때까지 대기
rt_task_sleep(rt_timer_ns2ticks(1000000000));
rt_timer_stop(&my_timer);
```

***

Xenomai의 Alchemy API는 기존의 POSIX API와 유사한 인터페이스를 제공하여 실시간 애플리케이션 개발을 용이하게 한다. 스레드 관리, 동기화 및 통신, 타이머 등의 기능을 통해 다양한 실시간 기능을 구현할 수 있으며, 이를 통해 높은 신뢰성과 성능을 요구하는 실시간 시스템을 구축할 수 있다.

위의 예제들은 Xenomai Alchemy API를 사용하는 방법에 대한 간단한 개요를 제공한다. 더 깊이 있는 정보와 예제는 Xenomai의 공식 문서와 관련 자료를 참고하시기 바란다.
