노무현 대통령 배너


2006. 8. 10. 10:38

[응용] 프로그램 자동 실행

출처: http://kelp.or.kr/korweblog/stories.php?story=04/09/06/5915586

[응용] 프로그램 자동 실행
글쓴이 : 유영창 (2004년 09월 06일 오후 01:45) 읽은수: 4,678 [ 임베디드강좌/유영창 인쇄용 페이지 ]
ADK002 프로그램 자동 실행
====================================

1. 개요

이 문서는 ESP-NS에서 동작하는 응용 프로그램을
부팅시에 어떻게 자동으로 실행시키는가를 설명한
문서입니다.

작성자 : 유영창
frog@falinux.com
작성일 : 2004년 9월 6일
수정일 :

관련된 ADK( Application Developer Kit ) 디렉토리

없음

2. 데몬 프로그램형식으로 작성해야 하는가?

응용 프로그램을 만들때 잠깐 고민하는 것이
계속 혼자서 동작하는 프로그램이니 데몬 형식으로 동작하도록
작성해야 하는가에 대한 고민입니다.

상황에 따라서 다르지만 과연 그럴 필요가 있을까요?

본인의 생각을 묻는다면 "아니다"라고 대답하고 싶습니다.

특별한 경우가 아니라면 프로그램을 작성할때 디버깅 과정에서
화면에 데이터 출력도 해야 하고 키를 이용해서 입력도 받을 필요가
있고 crtl-c 키로 프로그램을 강제로 중지 시킬 필요가 있습니다.

데몬은 이런 처리를 하지 않는 전제 조건으로 동작하는 프로그램입니다.

그러므로 프로그램은 일반적인 형식의 프로그램으로 만든후
실행할때 백그라운드로 동작 시키는 것이 났습니다.

혹시 리눅스에서 백그라운드로 프로그램을 실행하는 방법을
모르시는 분을 위해서 간다하게 설명하면 다음과 같이 끝에 '&' 문자만
붙여주면 됩니다.

[root@ /test/bin/] test &


다 아는 것인데 괜히 썼나 (흠흠.. )

3. 프로그램을 자동으로 실행하기 위해서는 어떻게 해야 할까?

ESP-NS 에서 동작하는 응용 프로그램을 작성했다면 응용 프로그램을
보드의 전원이 켜진후 동작하도록해야 합니다.

그렇다면 어디에서 프로그램을 자동으로 실행해야 할까요?

자동 수행 시킬 위치는 이미 정해져 있기 때문에 몇 군데 받에 없습니다.
그 위치는 다음과 같습니다.

1) /sbin/init 프로그램을 대치하는 방법
2) /etc/inittab을 이용하는 방법
3) /etc/rc.d/rc.local을 이용하는 방법
4) /etc/rc.d/rc.sysinit를 이용하는 방법
5) /etc/rc.d/init.d 디렉토리에 두고 이용하는 방법

이 방법중 본인이 주로 사용하는 방법은 /etc/rc.d/rc.local을 이용하는
것입니다.

각 위치에 따른 장단점을 알아봅시다.

3.1 /sbin/init 프로그램을 대치하는 방법

별로 추천하고 싶지 않는 방법입니다.
왜냐하면 응용 프로그램의 디버깅 단계에서
정상적인 리눅스 콘솔을 볼수 없기 때문에 개발하기 까다롭습니다.
즉 쉘을 구경할 수도 없고 기타 등등의 상황이 발생합니다.

그러나

시스템에 주어진 메모리도 작고 플래쉬 메모리가 작은 경우라면
한번쯤 검토할만 합니다.

시스템이 동작하기위해서 하나의 실행파일로 모든 것이 끝난다면
실행파일에 참조하는 라이브러리를 모두 스텍틱 처리해서
단 하나의 실행파일을 실행하는 것으로 모든 것이 끝나기 때문입니다.

pork를 이용해서 다른 프로그램을 수행할수도 있습니다.

라이브러리가 실행 파일에 포함되기 때문에 LGPL의 적용
대상이 되지 않기 때문에 소스를 공개할 의무를 가지는
단점이 있다는 것 역시 기억하여야 합니다.

물론 라이브러리를 응용 프로그램에 포함시키지 않는 방법이
있지만 그렇다면 그 큰 라이브러리가 모두 시스템에 올라가야
하므로 얻어지는 것이 별로 없겠죠?


3.2 /etc/inittab을 이용하는 방법

init 프로그램은 리눅스가 동작하면서 가장 먼저 수행되어
시스템에 필요한 처리를 하는 프로그램을 동작 시키고
대기하는 프로그램입니다.

이 방식을 사용하여 얻어지는 이점은 사용법이 간단하다는 것입니다.
그리고 프로그램이 죽으면 다시 자동으로 실행시켜 줍니다.

프로그램을 추가 하는 방법은 다음과 같습니다.

/etc/inittab의 끝 부분에 다음과 같이 사용하면 됩니다.

===[/etc/inittab]================================================
:
APP0:12345:respawn:/test/bin/testprogram debugging
===[/etc/inittab]================================================

inittab의 사용법에 대한것은

info inittab

으로 알아보기 바랍니다. 아마 아주 자세하게 설명하고 있읍니다.
배포판에 따라서 한글로 아주 자세하게 나옵니다.

위 예는 런레벨 12345일때 /test/bin/testprogram을 실행합니다.
만약에 이 프로그램이 어떤 원인이 있어서 죽었다면 다시 실행시켜 줍니다.
마지막에 있는 debugging은 프로그램 아규먼트로 전달되는 것입니다.
이 부분은 필요없으면 안쓰면 그만입니다. 단지 전달되는 예를 보여 준것이다.

만약에 한번만 실행될 필요가 있다면 respawn 대신에 once를 사용합니다.
런 레벨을 무시하고 부팅시에만 실행될 필요가 있다면 boot를 씁니다.

respawn , once, boot는 프로그램의 종료를 기다리지 않고 다음을 진행합니다.

하지만 경우에 따라서는 프로그램이 실행되고 끝난후에 다음을 진행할 필요가 있습니다.
이때는

respawn 대신에 wait를 boot 대신에 bootwait를 사용합니다.

이렇게 좋은 방법이 있음에도 불구하고 본인은 이 방법을 잘 사용하지 않습니다.

왜?

respawn을 사용했는데 프로그램이 죽는 상황이 프로그램 시작 초기에 발생하면 부팅 초기에
(특히 개발단계에서) 죽어라 죽은 프로그램을 다시 실행하기 위해서 init
프로그램은 애씁니다.(보기에 안쓰러울 정도 입니다. ㅜㅜ).
이 경우라면 부팅시간이 무척 길어져서 콘솔 화면 보기 정말 더럽게 어렵습니다.
(당해봐야 압니다.)

아니면 wait 를 이용했을경우에는 아예 부팅 스크립트들이 진행되지 않기 때문에
콘솔 보기는 애초에 포기해야 합니다. ( 이런 상황에 닥지면 정말 귀찮죠.. )

보통 임베디드 응용 프로그램은 하나만 수행하지 않습니다. 프로그래머의 취향에 따라
다르지만 본인이 경우는 그렇습니다. 여러 프로그램을 실행할때는 보통 시작 순서가
있을 수 있습니다. 또 프로그램이 죽더라도 다시 실행을 바로 수행하지 않을 필요가 있습니다.
그리고 특정 디렉토리로 이동해서 프로그램이 시작되어야 하는 경우도 많습니다.
이런 경우에 inittab으로는 대처가 되지 않습니다.

그..래..서

이런 저런 제약 조건 때문에 본인은 그 막강한 기능에 비해서 잘 사용하지 않습니다.

3.3 /etc/rc.d/rc.local을 이용하는 방법

요기가 필자가 주로 사용하는 방법입니다.
ESP-NS는 inittab에 이 스크립트를 처리하도록 하는 부분이 포함되어 있으므로
반드시 수행해 줍니다

프로그램을 부팅시에 동작하게 하도록 하기 위해서 이 파일 끝부분을 애용합니다.

간단한 스크립트 문법도 적용되고 환경 설정 내용도 사용할수 있기 때문에
무척 편리합니다.

아주 간단한 예를 보여 드리겠읍니다.

===[/etc/rc.d/rc.local]================================================
:

# 프로그램을 시작한다.
echo "DVR Program Start"

cd /app/bin
./network_module &
./parameter_module &
./recoding_module &
./play_module &
sleep 1
./main_module &
===[/etc/rc.d/rc.local]================================================

보시다 시피 그냥 쉘에서 키보드로 입력하는 내용을 그대로 써 넣어 주면 된다.

쉽죠?

이 부분을 사용하는 것은 스크립트 명령 문법을 많이 알고 있을수록 유리합니다.

3.4 /etc/rc.d/rc.sysinit를 이용하는 방법


이 파일을 이용하는 것은 /etc/rc.d/rc.local을 사용하것과 유사하기 때문에
더 이상의 설명을 하지 않겠읍니다.

그..러..나..

이 부분은 시스템 초기 설정과 관련된 사항이 많고 가장 처음 실행하는
부분입니다.

그..래..서..

가급적 사용하지 않는 것이 좋습니다.

3.5 /etc/rc.d/init.d 디렉토리에 두고 이용하는 방법

이것은 보통 PC 의 리눅스에서 셋업처럼 동작하는 부분입니다.

수행되어야 하는 프로그램을 위한 스크립트를 /etc/rc.d/init.d
에 넣고

각 런레벨에서 수행하는 디렉토리에서 링크를 시키는 방법입니다.

예를 들어

/etc/rc.d/init.d 에 test_sample 이라는 스크립트가 있다면

런레벨 3에서 수행하도록 하려면

cd /etc/rc.d/rc3.d/
ln -s ../init.d/syslog S10test_sample

하면 됩니다. 링크 파일을 만들때 주의 할점은
가장 첫번째 문자가 'S' 이면 시작을 'K'면 시스템을 셧다운 할때
동작한다는 의미이고

그다음 두문자의 숫자는 실행 순서를 의미 합니다.


4. 기타

경우에 따라서는 자동 로긴을 해서 실행할 필요가 있는 경우가 있습니다.
이경우는 따로 로깅 프로그램이 필요한데
본인은 잘 사용하지 않았기 때문에 설명하지 않겠습니다.

KELP 에 가시면 어떤 친절한 분이 써 놓은 글이 있읍니다.
링크 위치는 잘 모르겠읍니다. 찾아 보세요 ㅜㅜ

[응용] 프로그램 자동 실행 | 답장: 3개(RSS) | 본문에 답장
정렬 :

답장 dawnsea (2004년 09월 07일 오전 09:33)
에이전트 프로그램을 하나 만들어서
주기적으로 어플리케이션 프로그램들의 상태를 체크하고
죽은 놈은 살리고 살린놈은 잘 보고 있는 방식도 좋은 것.. 같습니다.

데몬은 꼭 필요한 경우가 아니면
덩치큰 프로그램의 경우 1바이트의 메모리 닉들이 수일 후에
뻗게 만들어서 종종 디버깅을 곤란하게 하는 경우도 있으니까요 ㅠ.ㅠ

에이전트 프로그램을 심플하고 완벽하게-_-; 구성하고
이 놈이 다른 프로그램들의 런쳐, 킬, 재실행들을 관리하는 방법도
하나의 방안이 될 것.. 같네요;;; (자신이 없어서;;;; ㅡ.ㅡ;)

제가 예전에 했던 방법은.
커널에 main.c 에서 아예 수정해서 볼일들을 미리 보고
자체 쉘... 쉘이라기 보다는 간단한 시스코 타입
CLI (Command line interface)를 띄우면서 CLI의 명령어 중에
쉘로 빠져나가는 (사실은 쉘을 실행시키는) 식으로 짰던 기억이 나네요.
[ 이글에 답장 | 본문에 답장 ]


답장 유영창 (2004년 09월 07일 오후 03:26)
에이전트를 이용하는 방법에 대해서 전적으로 동의합니다.

저는 에이전트라고 하지 않고 그냥 슈퍼데몬이라고 합니다.
그렇다고 데몬은 아니지만
원격 소프트웨어 업그레이드까지 처리하도록
하는 프로그램이죠 저 나름대로 이름을 짓는 것이죠..

제가 가장 좋아 하는 방식입니다.

소개를 안했던 이유는

에이전트라는 프로그램을 작성하는 거은
처음 작성하는 분들에게는
어려운 일이 될수도 있다고 생각해서요 ^^

그리고 계속적인 충고 부탁 드립니다. (꾸벅)
[ 이글에 답장 | 본문에 답장 ]

답장 익명 (2004년 10월 27일 오전 09:49)
슈퍼데몬을 어떤식으로 짜야 할지..

1. 슈퍼데몬에서 H/W Watchdog에 펄스를 주면서 동시에
S/W Watchdog도 제어를 하면서,

2. 어플리케이션을 감시하다가 어플리케이션이 죽었을경우는
우선 어플리케이션을 살려보고 그래도 죽을때는 리셋을 주고

3. CPU가 완전히 죽었을때는 H/W watchdog가 실행되어 리셋되고 싶습니다.

구현하려고 했더니 문제시 되는건 데몬을 Watchdog드라이버에서 동작시키자니
드라이버에서 어플리케이션을 실행할수 없고,
에이젼트를 만들자니 어플리케이션과의 통신을 어떻게 해야할지 고민입니다.

조언부탁드립니다.