- Xenomai Cobalt 패치가 반영된 ARM Sabre Lite 리눅스 커널에서 애플리케이션을 테스트한다.
설치 환경
- ‘리눅스 커널 빌드 - ARM Sabre Lite(Kernel.org)’ 또는 ‘리눅스 커널 빌드 - ARM Sabre Lite(NXP)’ 글을 참고하여 Sabre Lite에 리눅스가 올라가야 한다.
- 타겟: Sabre Lite에 Linux kernel 4.14.85 Xenomai-3.0.8 ipipe(Cobalt)
타겟에 Xenomai 라이브러리 설치
- Xenomai 라이브러리는 Cobalt 커널과 Mecury 커널 모두 사용 가능하다.
- Mecury 커널의 경우는 Xenomai 라이브러리를 사용하여 태스크를 생성하는 경우, 리눅스 커널에서 실행디고 실시간성은 리눅스 커널에 의존한다.
1
2
3
4
5
6
7
8
$ wget https://xenomai.org/downloads/xenomai/stable/xenomai-3.0.8.tar.bz2
$ tar xfvj xenomai-3.0.8.tar.bz2
$ cd xenomai-3.0.8
$ make distclean
# 기본적인 Xenomai 라이브러리 설정 명령어, 자세한 설정은 하단 출처를 참고
$ ./configure CFLAGS="-march=armv7-a -mfpu=vfp3" --with-pic --with-core=cobalt --enable-smp
출처: https://gitlab.denx.de/Xenomai/xenomai/wikis/Installing_Xenomai_3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Xenomai 라이브러리 빌드
$ sudo make -j4
# Xenomai 라이브러리 설치
$ sudo make install
# root 계정으로 로그인
$ su
# Xenomai 관련 환경 변수 등록
$ echo '
### Xenomai
export XENOMAI_PATH=/usr/xenomai
export PATH=PATH:XENOMAI_PATH/bin:XENOMAI_PATH/sbin
export LD_LIBRARY_PATH=LD_LIBRARY_PATH:XENOMAI_PATH/lib
' >> ~/.xenomai_rc
echo 'source ~/.xenomai_rc' >> ~/.bashrc
source ~/.bashrc
# Xenomai 설치 확인(Xenomai latency 확인)
$ sudo /usr/xenomai/bin/latency
Xenomai 애플리케이션 테스트
- Tab 문자 적용할 때 시스템 내에서 설정된 공란(space) 크기 확인이 필요하다.
- 해당 애플리케이션은 Xenomai에서 제공하는 자체 RTOS API인 Alchemy다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<Makefile>
XENO_CONFIG := /usr/xenomai/bin/xeno-config
CFLAGS := (shell (XENO_CONFIG) --alchemy --cflags)
LDFLAGS := (shell (XENO_CONFIG) --alchemy --ldflags)
CC := (shell (XENO_CONFIG) --cc)
EXECUTABLE := start
all: (EXECUTABLE)
start: start.c
(CC) -o @ < (CFLAGS) (LDFLAGS)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<start.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <math.h>
#include <sys/mman.h>
#include <alchemy/task.h>
#include <alchemy/timer.h>
#define CLOCK_RES 1e-9 //Clock resolution is 1 ns by default
#define LOOP_PERIOD 1e7 //Expressed in ticks
//RTIME period = 1000000000;
void print_hello(void);
void loop_task_proc(void *arg) {
RT_TASK *curtask;
RT_TASK_INFO curtaskinfo;
RTIME tstart, now;
int cnt = 0;
// Retrieve information from current task
curtask = rt_task_self();
rt_task_inquire(curtask, &curtaskinfo);
//Print the info
printf("task info \n");
printf("curtaskinfo.name: %s\n", curtaskinfo.name);
printf("curtaskinfo.pid: %d\n", curtaskinfo.pid);
printf("curtaskinfo.prio: %d\n", curtaskinfo.prio);
//Make the task periodic
// current task, release date(current system date), period
rt_task_set_periodic(NULL, TM_NOW, LOOP_PERIOD);
tstart = rt_timer_read();
//Start the task loop
while (1) {
printf("Loop count: %d, Loop time: %.5f ms\n", cnt,
(rt_timer_read() - tstart) / 1000000.0);
cnt++;
rt_task_wait_period(NULL);
}
}
int main(int argc, char **argv) {
RT_TASK loop_task;
//Lock the memory to avoid memory swapping for this program
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("Starting cyclic task...\n");
//Create the real time task
rt_task_create(&loop_task, "basicmath_small", 0, 50, 0);
//Since task starts in suspended mode, start task
rt_task_start(&loop_task, &loop_task_proc, 0);
//Wait for Ctrl-C
pause();
return 0;
}
1
2
3
4
5
# 빌드, 쿼드코어 사용
$ make -j4
# Xenomai 애플리케이션 실행
$ sudo ./start
Comments powered by Disqus.