Docker 탐구

[Docker 탐구 - 2] Docker를 이용한 간단한 Xenomai API 호출 프로그램 구동

겨울꿈개발자 2021. 4. 7. 00:04

앞에 글에서는 ARM OS 사용을 위해 Docker를 설치하고 간단하게 사용한 과정을 소개하였습니다.

dream-winter.tistory.com/19

 

[Docker 탐구 - 1] Docker를 이용한 ARM OS 사용

만약 어떠한 프로그램 코드를 ARM 보드에서 크로스 컴파일하여 실행 파일을 만들었으나, 어떠한 이유로 인해 해당 보드가 없는 상황이라고 가정해봅시다. 기존의 방법이라면, 해당 실행 파일은

dream-winter.tistory.com

이번 글에서는 Docker를 이용하여 Xenomai 포팅된 OS를 사용하고, 해당 OS에서 간단한 Xenomai API를 사용하는 프로그램을 만들어보겠습니다.


Xenomai 패치된 OS container 실행 과정

docker hub 내 "iiclab/ubuntu"로부터 관련 image를 찾을 수 있었으며, 이를 가져와서 container로 실행하였습니다.

xenomai 패치된 ubuntu image를 여러 버전으로 제공하고 있기에 태그로 구분하여 가져옵니다.

docker pull iiclab/ubuntu:16.04-xenomai-3.0.3-mercury

간단한 소스 코드 작성을 위해 vim 설치를 하였습니다

apt-get update -y && apt-get install vim

아래 코드를 작성하였습니다.

rt_task_create, rt_task_start 라고 하는 xenomai 실시간 태스크 생성 및 실행 함수를 호출하여 간단한 printf 구문을 출력합니다. 실시간 태스크에 printf, sleep과 같은 함수를 쓰면 실시간성에 문제가 있을 수 있지만, 단순히 xenomai API가 잘 호출되기 위한 프로그램이니 우선 추가하였습니다.

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

void task_func();

int main()
{
    int err = 0;
    RT_TASK rt_task;

    if((err = rt_task_create(&rt_task, "rt_task", 0, 50, 0)) != 0)
    {
        printf("task create failed = %d\n", err);
        return err;
    }

    if((err = rt_task_start(&rt_task, &task_func, 0)) != 0)
    {
        printf("task start failed = %d\n", err);
        return err;
    }

    while(1)
    {
        sleep(1);
    }
}

void task_func()
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("task loop %d\n", i);
        sleep(1);
    }
}

xenomai 관련 헤더 및 라이브러리를 사용하기 위해 xeno-config를 사용합니다.

해당 파일의 위치를 찾기 위해 아래 명령을 통해 /usr/xenomai/bin/xeno-config 경로에 있음을 확인합니다.

find / -name 'xeno-config'

xeno-config는 특정 인자와 함께 실행하면 cflags, ldflags를 출력하는 스크립트입니다.

sh /usr/xenomai/bin/xeno-config --skin native --cflags
sh /usr/xenomai/bin/xeno-config --skin native --ldflags

해당 결과물을 이용하여 빌드하기 위해 역따옴표(`) 문자를 사용합니다.

gcc test.c `sh /usr/xenomai/bin/xeno-config --skin native --cflags` `sh /usr/xenomai/bin/xeno-config --skin native --ldflags`

이후 실행하려고 하니 libalchemy.so.0을 찾을 수 없다는 문구가 출력됩니다. find 명령을 통해 해당 파일을 찾고 LD_LIBRARY_PATH 환경 변수에 해당 경로를 넣어줍시다. 해당 변수가 기존에 값이 없었으니 그냥 바로 넣어줬습니다.

export LD_LIBRARY_PATH=/usr/xenomai/lib

이후 실행한 결과 RT 태스크 함수 내의 printf 출력 결과가 잘 나온것을 확인하였습니다.

프로그램 실행 결과

위의 실행 결과에서 경고문이 출력된점이 좀 신경쓰입니다. xenomai 환경을 제대로 이용하기 위해서는 docker의 추가적인 설정이 필요할 수 있습니다. 우선 저는 실시간성을 타이트하게 지키는 것보다는 우선 docker를 통해 xenomai API를 사용하는 프로그램의 실행 가능성을 확인하는 것이 목적이기에 설정과 관련해서는 추후 필요할 경우에 찾아볼 예정입니다.


추후 docker 사용 계획 - Xenomai 패치된 ARM 환경 사용

이번 글에서는 xenomai가 패치된 amd64 환경을 사용을 해봤습니다.

저는 우선 xenomai가 패치된 arm 환경을 사용하고 싶으나, 아직은 해당 image를 직접 찾지는 못했습니다.

아마 직접 만들어야 할 수도 있을 것 같습니다.

 

현재 생각하고 있는 방법은 크게 2가지입니다.

1. rootfs를 이용하여 docker image 생성

2. arm docker image에서부터 직접 xenomai를 패치하여 새로운 image를 만드는 방법

 

첫번째 방법의 경우에는 인터넷에서 찾아본 결과, linux root filesystem을 docker import 명령어를 이용하여 image로 만들 수 있다고 합니다. 제가 아직 root filesystem을 직접 추출해본적이 없는데, 해당 방법이 된다면 가장 쉽게 docker image를 만들 수 있는 방법으로 보입니다.

 

두번째 방법은 이번 글에서 사용한 xenomai 패치된 amd64 docker image를 참고하여 이전 글에서 사용한 arm docker image에서 직접 xenomai를 패치하는 방법입니다. docker desktop에서 해당 image RUN 버튼 옆의 ...을 누르고 inspect 버튼을 클릭하면 해당 image가 만들어진 과정을 볼 수 있습니다. 해당 과정 내에서 xenomai 패치하는 과정을 확인할 수 있으며, arm 버전에 맞는 xenomai 커널만 찾을 수 있으면 해당 과정을 참고해서 패치할 수 있을 것 같습니다.

docker image history


여담

docker를 보면서 든 생각입니다. 여러 개의 기능을 제공하는 서비스가 있다고 생각할 경우에 각 기능들을 docker container로 각각 구현하고, container 간 통신을 하면, 하나의 서비스를 구축할 수 있을 거 같습니다.

 

최근 여러 공부를 하고 있습니다. 여러 개의 docker container를 관리하기 위해 kubernetes가 있다고 합니다.

조만간 이를 사용해 볼 기회가 왔으면 좋겠습니다.

 

ROS라고 하는 로봇 운영체제도 특정 기능들을 수행하는 여러 개의 노드들로 구성된 시스템이라고 보여집니다. 마치 서로 닮은 거 같은 느낌이 듭니다. 결국 시스템들의 핵심 맥락은 비슷한가 봅니다.

 

dream-winter.tistory.com/8

 

ROS 소개

ROS(Robot Operating System)는 로봇 제어에 필요한 다양한 s/w 기능들을 제공하는 오픈 소스 플랫폼입니다. Ubuntu Linux에서 사용되었는데, Windows에서도 사용할 수 있는 ROS2도 있습니다. ROS는 마스터, 노드.

dream-winter.tistory.com