Xenomai가 컴파일되고 설치된 후, 우리가 실행하려는 시스템에서 제대로 작동하는지 확인하는 과정이 필요하다. 이 절에서는 Xenomai의 설치를 확인하는 방법을 다룬다.
uname으로 확인
가장 먼저, 적절한 Xenomai 커널이 로드되었는지 확인해야 한다. 이를 확인하려면 uname
명령어를 사용한다.
uname -a
이 명령어는 현재 커널과 관련된 모든 정보를 출력한다. 만약 Xenomai가 올바르게 설치되었고 현재 커널에 패치되었다면, 출력 결과에 Xenomai
라는 단어가 포함되어 있어야 한다. 예를 들어:
Linux hostname 5.4.50-xenomai-3.1.x #1 SMP PREEMPT Wed Jun 24 14:31:21 PDT 2020 x86_64 GNU/Linux
위의 예에서 5.4.50-xenomai-3.1.x
는 Xenomai가 커널에 제대로 패치되었음을 나타낸다.
xeno-test로 성능 테스트
Xenomai 배포판은 다양한 테스트 프로그램을 제공하며, 이러한 프로그램들을 통해 시스템이 실시간 요구 사항을 충족하는지 확인할 수 있다. 그 중 xeno-test
는 기본적인 성능 테스트를 수행하며 Xenomai 설치 확인의 중요한 도구이다.
xeno-test
를 실행한다:
sudo /usr/xenomai/bin/xeno-test
- 테스트 결과를 분석한다:
- 테스트가 성공적으로 완료되면, 각종 통계 정보와 시스템의 실시간 응답 시간에 대한 정보가 표시된다.
- 실패하거나 비정상적으로 높은 지연 시간이 발생하는 경우, 커널 설정 또는 하드웨어 구성의 문제일 수 있다.
latency 테스트
latency
테스트 프로그램은 시스템의 실시간 성능을 측정하는 또 다른 유용한 도구이다. 이 프로그램은 시스템의 최대 및 평균 지연 시간을 보여준다.
latency
프로그램 실행:
sudo /usr/xenomai/bin/latency
- 테스트 결과 분석:
- 이 테스트는 시스템의 최대 지연 시간과 평균 지연 시간을 표시한다.
- 일반적으로 실제 실시간 시스템에서는 지연 시간이 마이크로초 단위에서 유지되어야 한다.
dual-core 시스템에서의 확인
듀얼 코어 시스템이나 멀티 코어 시스템에서는 각 코어가 실시간 요구사항을 적절히 처리하는지 확인해야 한다. 이를 위해, Xenomai는 klatency
테스트 프로그램을 제공한다.
klatency
프로그램 실행:
sudo /usr/xenomai/bin/klatency
- 결과 분석:
- 테스트 동안 각 코어에서 발생하는 최대 및 평균 지연 시간을 모니터링할 수 있다.
- 각 코어의 지연 시간이 실시간 요구사항을 충족하는지 확인한다.
이제 Xenomai가 올바르게 설치되고 시스템이 실시간 요구 사항을 제대로 처리할 수 있는지 확인되었으므로, 간단한 예제를 통해 실제로 Xenomai 애플리케이션을 작성해본다. 이 예제에서는 가장 기본적인 Xenomai 실시간 태스크를 생성하고 실행하는 방법을 보여준다.
코드 작성
아래는 Xenomai 프로그램을 작성하는 기본 예제이다. 이 예제는 실시간 태스크를 생성하고 주기적으로 메시지를 출력하는 프로그램이다.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <alchemy/task.h>
#define TASK_PRIO 99 /* Highest RT priority */
#define TASK_MODE 0 /* No flags */
#define TASK_STKSZ 0 /* Default stack size */
#define TASK_PERIOD 1e9 /* 1 second in nanoseconds */
RT_TASK demo_task;
void catch_signal(int sig)
{
/* Handle CTRL+C to exit program */
printf("Exiting program\n");
rt_task_delete(&demo_task);
exit(0);
}
void demo(void *arg)
{
int count = 0;
rt_task_set_periodic(NULL, TM_NOW, TASK_PERIOD);
while (1) {
rt_task_wait_period(NULL);
printf("task execution, count = %d\n", ++count);
}
}
int main(int argc, char *argv[])
{
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
/* Avoids memory swapping for this program */
mlockall(MCL_CURRENT | MCL_FUTURE);
/* Create real-time task */
rt_task_create(&demo_task, "Xenomai_demo_task", TASK_STKSZ, TASK_PRIO, TASK_MODE);
/* Start real-time task */
rt_task_start(&demo_task, &demo, NULL);
pause();
return 0;
}
컴파일
작성한 Xenomai 프로그램을 컴파일하기 위해 알맞은 컴파일 명령어를 사용해야 한다. 이 예제 프로그램을 demo.c
파일로 저장했다면, 다음과 같이 컴파일할 수 있다:
gcc -o demo demo.c -lxenomai -lpthread -lnative
실행
이제 프로그램을 실행하여, 실시간 태스크가 주기적으로 메시지를 출력하는지 확인할 수 있다:
sudo ./demo
프로그램이 성공적으로 동작한다면, 출력 창에 주기적으로 task execution, count = n
과 같은 메시지가 출력된다. 여기서 n
은 현재 실행 주기를 나타낸다.
시그널 처리
위 예제에서는 CTRL+C 나 SIGTERM 시그널을 받아 프로그램이 안전하게 종료될 수 있도록 시그널 핸들러를 등록하였다. 이 핸들러는 실시간 태스크를 삭제하고 프로그램을 종료한다.
메모리 잠금
mlockall(MCL_CURRENT | MCL_FUTURE)
함수 호출은 프로그램이 메모리 스왑으로 인해 지연되지 않도록 메모리를 잠급니다. 실시간 시스템에서는 매우 중요한 작업 중 하나이며, 예기치 않은 메모리 스왑으로 실시간 응답성이 떨어지는 것을 방지한다.
이로써 기본적인 Xenomai 실시간 태스크 프로그래밍 방식을 익혔습니다. 이제 이를 토대로 더욱 복잡하고, 다양한 실시간 애플리케이션을 개발할 수 있다.