본문 바로가기

Hacked Brain/embeddedland.net

임베디드 시스템에 쓰이는 운영체제 - 2

 

저 자 : 송인준

출판일 : 2003년 8월호
 

임베디드 시스템의 반대말은 범용 시스템?
임베디드 시스템을 어떤 특화된 목적을 위한 시스템으로 생각해 본다면 그 반대의 개념으로는 범용 시스템을 들 수 있습니다. 그렇다면 그 차이는 무엇일까요? 어떠한 개념을 확립하는데 있어서 그 반대되는 개념과의 차이를 명확히 구분짓는 것이 중요합니다.


시스템과 그 위에서 돌아가는 응용 프로그램의 관계를 설명하면서 두 개념을 풀이하면 범용 시스템은 응용 프로그램 자체가 시스템에게 맞추어 가는 것이고, 그에 반해 임베디드 시스템은 시스템이 응용 프로그램에게 맞추어 가는 것입니다. 이렇게 시스템이 응용 프로그램에게 맞추어가는 것을 Application Specific System이라고 합니다. 즉, 여러 가지 목적을 위한 범용 시스템은 하나의 시스템이 있고 그 위에서 수행될 응용 프로그램이 있고, 임베디드 시스템은 하나의 특화된 목적을 가진 응용 프로그램이 있고 그에 적합하게 시스템은 모습을 갖추는 것이 둘의 차이점이라 할 수 있습니다.


임베디드 시스템의 실시간 시스템적 특성
여러분에게 질문하겠습니다. 과연 임베디드 시스템은 운영체제일까요? 임베디드 운영체제(Embedded OS)는 무엇일까요?


임베디드 시스템은 단지 시스템일 뿐이지 운영체제는 아닙니다. 임베디드 운영체제는 임베디드 시스템을 구동하는 운영체제입니다. 그렇다면 임베디드 운영체제에는 무엇이 있을까요? 특정 시스템에 어떠한 운영체제가 쓰일지를 결정짓는 것은 그 시스템의 활용 의도입니다. 이 시스템이 과연 어느 목적으로 쓰일 것인지가 중요한 것이지요. 임베디드 시스템에도 여러 가지 목적이 있으므로 어떠한 운영체제를 사용할지는 각 시스템에 따라 다릅니다. 하지만 한 가지 공통점이 있는데, 대부분의 임베디드 시스템에서는 실시간 운영체제(Real-Time Operating System)를 주로 쓴다는 점입니다. 왜 실시간 운영체제가 임베디드 시스템에 주로 쓰이게 되는 것일까요.


예를 들어, 휴대폰을 가정해 보죠. 우리가 열심히 휴대폰으로 재밌는 고스톱 게임을 하고 있을 때, 중요한 전화가 왔다면 어떻게 해야할까요. 만약 범용 시스템에서 쓰이는 일반적인 운영체제였다면 전화가 오는 태스크는 프로세스 스케쥴링되어질 것입니다. 그렇다면 타임 퀀텀에 따라 언젠가는 전화가 오는 태스크가 CPU를 잡고 실행하게 될 것입니다. 하지만 이렇게 되면 중요한 전화를 놓치는 일이 빈번히 발생할 테죠. 하지만 실시간 운영체제의 스케쥴링은 타임 퀀텀을 나누는 것이 아니라, 우선순위 기반의 스케쥴링이기 때문에 우선순위가 높은 전화를 위한 프로세스가 CPU를 잡고 실행될 것입니다. 이렇게 대부분의 임베디드 시스템은 외부 반응에 즉각적인 응답을 해야 하는 게 대부분이기 때문에 주로 실시간 운영체제를 사용하는 것입니다. 이렇게 임베디드 시스템에는 실시간적 특성이 있습니다. 그러므로 대개의 임베디드 시스템에서는 실시간 운영체제를 사용합니다. 그렇다면 임베디드 시스템에 주로 사용되는 실시간 운영체제의 기본적인 개념들을 살펴보도록 합시다.


실시간 운영체제의 개념
실시간 운영체제를 정확히 정의하자면, 시간의 제한을 갖고 그 시간 제한 안에 정확한 결과를 내기 위한 시스템을 구동시키고 시스템을 위해 여러 가지 실시간 작업에 대한 스케쥴링 등의 일을 처리해주는 운영체제를 말합니다. 결국 실시간 시스템이 범용 시스템에 비해 충족해야 할 조건은 시간의 제한을 지켜야 한다는 점과 그 데드라인 안에 정확한 결과를 내주어야 한다는 점입니다. 만약 핵 발전소 같은 곳에서 임계온도를 넘어가면 위험한 상황일 때, 이에 대한 처리를 긴급히 또한 정확히 해주어야 겠지요.


잘 알려진 범용 운영체제인 리눅스를 이용하여 실시간 운영체제를 설명해 보겠습니다. 먼저 리눅스는 실시간 운영체제가 아닙니다. 리눅스는 시분할 시스템으로 설계되어 공정성에 기반한 스케쥴링 알고리즘을 사용합니다. 그러나 실시간 운영체제에서는 프로그램마다 우선순위가 고정되어 있으며, 그 우선순위를 기반으로 상대적으로 높은 우선순위의 작업이 실행될 준비가 되었다면 스케쥴러가 현재 수행중인 작업을 중단하고 높은 우선순위의 작업으로 전환될 수 있어야 합니다. 더욱이 리눅스 커널은 사용자 프로세스에 의해서 재진입이 가능하지도 않으며 다른 프로세스가 커널 모드에서 실행되고 있는 것을 끊고 실행되지도 않습니다. 커널의 자원을 이용하고 있는 프로세스가 있다면 그 프로세스가 대기상태로 가거나 종료하지 않는 이상 다른 프로세스들이 실행될 수 없습니다. 즉, 일정한 응답시간을 가져야 할 실시간 작업이 리눅스 커널 하에서 실행된다면, 최악의 경우 커널 내부의 코드를 실행하다가 응답시간을 넘길 수도 있다는 이야기입니다. 이러한 것은 엄격하게 말해 실시간적인 요구사항을 제대로 반영하지 못한다는 것입니다.


이러한 실시간 시스템은 두 가지 종류가 있습니다. 소프트 실시간 시스템(soft realtime system)과 하드 실시간 시스템(hard realtime system)이 있습니다. 전자는 데드라인을 어느 정도 넘겨도 무방한 시스템으로 동영상을 재생하는 시스템의 경우에 사람이 움직임을 인지하기 좋은 프레임인 초당 24 프레임을 지원해야 하지만 어느 정도 시간을 넘겨도 잠시 기분 나쁘고 마는 정도가 되겠죠. 하지만 후자의 경우는 앞서 예를 들었던 핵 발전 제어 시스템과 같이 긴급히 중단 명령을 내렸을 때 1/100초라도 오차가 생기면 안 되는 그러한 시간에 매우 엄격한 시스템을 말합니다. 다음의 <그림 1>은 이 두 가지 시스템과 데드라인의 관계를 보여주고 있습니다.


<그림 1> 소프트 실시간 시스템과 하드 실시간 시스템


지금까지 임베디드 시스템의 제한적인 자원과 특화된 목적을 갖고, 실시간적인 특성을 갖는다는 특성을 살펴보았습니다. 그렇다면 이러한 각 특성을 충족시켜주는 운영체제의 디자인 이슈에는 어떠한 것들이 있는지 살펴보도록 하겠습니다.


운영체제의 디자인 이슈
앞에서도 잠깐 언급했던 부분이지만 임베디드 시스템에서 제한된 자원인 배터리, 즉 전력의 사용은 크게 고려하지 않을 수 없는 부분입니다. 같은 배터리를 가지고 어떻게 관리하느냐에 따라서 시스템의 작동 시간에 차이가 생기기 때문입니다. 또한 전력에 의한 발열량도 생각할 수 있는 문제입니다. 전력관리를 위한 지원에는 여러 가지가 있습니다. 먼저 회로적인 수준에서 지원하는 방법과 시스템 수준에서 지원하는 방법이 있습니다. 회로 수준에서 지원하는 방법에는 동적 전압 스케일링(dynamic voltage scaling)과 클럭 게이팅(clock gating) 등이 있으며, 시스템 수준에서 지원하는 방법은 하드웨어, 소프트웨어, 그리고 운영체제를 통해 이루어집니다. 그럼 회로 수준에서는 동적 전압 스케일링 방법, 그리고 시스템 수준에서 운영체제에 의한 방법을 살펴보도록 하겠습니다.


동적 전압 스케일링
동적 전압 스케일링에서는 장치가 활성화된 상태에서 에너지 소비 레벨과 성능 간에 조정을 하는 것입니다. 대부분의 시스템들은 끊임없이 최고 성능을 내도록 고안되어 있습니다. 그러나 이러한 설계는 전력관리에 민감한 임베디드 시스템에서는 에너지의 낭비를 일으키게 됩니다. 동적 전압 스케일링의 핵심은 사용자에게 에너지를 절약하면서 성능을 만족시키도록 하는 것입니다. 다음 두 수식은 에너지와 전압 그리고 프로세서의 클럭 주파수 간의 관계를 보여주는 것입니다.


여기서 Eop는 연산에 필요한 에너지이며 fmax는 프로세서의 최대 클럭 주파수가 되며 V는 연산에 사용되는 전압입니다. 이 수식에서 알 수 있듯이 전압은 에너지와 주파수에 영향을 줍니다. 즉, 어떠한 작업을 수행하는데 소비되는 에너지를 줄이려면 전압을 줄이는 방법을 생각할 수 있으며, 전압을 줄이면 CPU의 클럭 주파수도 감소하게 됩니다.


임베디드 시스템에 사용되는 트랜스메타 크루소나 인텔 StrongARM, XScale과 같은 프로세서들이나 IBM PowerPC 405LP 등의 프로세서들은 동적인 전압과 프로세서 코어의 주파수 스케일링이 가능하여 이러한 에너지 효율적인 전력관리를 지원하고 있습니다.


운영체제에 의한 동적인 전력 관리
동적인 전력 관리(dynamic power management)라는 것은 한마디로 말하면 시스템 컴포넌트들의 전력 상태를 변화시킴으로써 성능 제약조건인 에너지 소비를 낮추는 것입니다. 여기에서 상태 변화는 완전하게 에너지를 사용하는 활성화(active) 상태와 저전력 상태 간에 일어나게 됩니다. 예를 들어 eCos라는 임베디드 시스템에 사용되는 운영체제에는 다음과 같은 상태들이 있습니다.


① active 상태 : 시스템은 완전히 작동가능하며 전력 소비는 높은 수준이 될 것입니다.


② idle 상태 : 짧은 시간 간격 동안 조금 혹은 거의 활동이 없게 됩니다. 짧은 시간 간격이 어떻게 구성되는지를 결정하는 것은 정책 모듈에 달려있습니다만, 보통 1/10초 혹은 몇 초가 될 것입니다. idle 모드에 진입했을 때 가능한 동작은 전압을 조정하여 시스템 클럭 속도를 낮추는 것입니다. 그에 따라서 CPU에 의해 소모되는 전력이 줄어들 것입니다.


③ sleep : 시스템은 대략 수십 초 정도의 큰 시간 간격동안 운휴상태가 됩니다. 스크린 백라이트(screen backlight)와 같은 많은 양의 전력을 소모하는 모든 하드웨어들의 작동을 중단시키는 것이 바람직할 것입니다.


④ off : 시스템은 전력이 중단됩니다. 전력 소비는 최소화가 되어야 할 것입니다. 시스템을 되돌리기 위해서는 몇 가지 특별한 동작이 요구되는데, 그것은 특정 버튼을 누르는 것 등이 될 것입니다.


이렇게 주어지는 상태들을 바꾸도록 명령을 주거나 시스템에서 전력 소비에 관련된 정보들을 수집하는 구성요소로서 전력 관리자(power manager)가 존재합니다. 전력 관리자는 시스템을 관찰하며 실행 시간에 반응하게 되는데, 전력 관리자가 내리는 결정들은 전력 관리 정책에 근거하게 됩니다. 전력 관리 정책은 시스템을 관찰하는 방법과 명령을 내리는 방법들을 제어하는 법률과도 같은 것입니다. 여기서 운영체제가 개입하는 이유는 운영체제는 시스템 상에 이루어지는 작업(task)이 수행 중인지 아니면 대기 상태인지를 알 수 있기 때문에 동적 전력 관리를 위한 정책 결정을 내릴 수 있기 때문입니다. 이러한 동적 전력 관리 기술은 크게 2가지로 나눠볼 수 있습니다. 첫 번째는 예측적인 방법이고 두 번째는 통계적인 제어 방법입니다.


예측적인 방법이란 말 그대로 idle 상태를 예측하여 미리 idle 상태로 바꾸어 상태 전환에 따른 지연시간을 줄이고자 하는 것이며, 주로 예측 정확도가 관건이 됩니다. 예측적인 방법에는 시간 경계 값(타임아웃)을 두어 일정 시간이 지나면 저전력 상태로 바꾸어 버리는 타임아웃에 근거한 방법과 과거 활성 및 비활성 상태의 정보를 기록하여 그것을 근거로 상태 변화를 예측하는 방법 등이 있습니다.


통계적인 제어 방법은 어떠한 사건이 일어나는 것을 정확히 예측하는 것은 본래 불가능하다는 가정 하에서 불확실성을 내포하는 추상화된 시스템 모델을 만들어 확률에 기초한 통계적 결정을 내리게 됩니다. 이러한 방법에는 통계에서 흔히 사용되는 마코프 체인(Markov Chain)을 이용하여 시스템과 시스템의 외부 환경을 모델링하는 CMP(Controlled Markov Process)라는 방법이 있습니다. 모델링을 통해 얻을 수 있는 이점은 전력 소비 함수를 최소화하고 성능 제약 조건을 충족시킬 수 있는 정책 P를 찾아내는 것입니다.


저장 매체의 한계를 극복한다
임베디드 시스템의 또 다른 특징으로 예를 들었던 저장 매체의 제한은 운영체제의 입장에서 상당히 까다로운 점입니다. 대개의 임베디드 시스템은 크기의 제약으로 하드디스크와 같은 장치를 사용할 수 없습니다. PDA 안에 하드디스크를 넣을 만한 공간이 있다면 크기가 얼마나 커질까요? 물론 플래시 롬과 같은 장치들을 사용할 수 있지만 근본적인 제약을 막지는 못합니다. 따라서 임베디드 시스템을 위한 운영체제는 그 크기도 매우 작을 뿐만 아니라 몇 가지 구조적인 변화를 겪고 있습니다.


메모리 구조의 변화
임베디드 시스템에 사용되는 메모리의 크기는 매우 작습니다. 기존의 PC나 유닉스 서버급에서 사용되던 운영체제는 효율적인 메모리 관리를 위해서 메모리 구조가 상당히 복잡하게 되어 있습니다. 실제 운영체제에서 사용되는 메모리 관리 구조는 세그먼테이션과 페이징을 비롯해서 각 페이지와 세그먼트마다 다른 종류의 프로텍션 모드를 가지고 있고, 이러한 전체 구조가 응용 프로그램마다 따로 관리되고 있습니다. 메모리 가격의 지속적인 인하는 대규모의 메모리를 장착하는 시스템을 만들게 되고 메모리의 제한이 급격하게 줄어들면서 메모리의 효율적인 사용보다는 안정적인 시스템을 구축하는데 더 큰 목적을 두게 된 것이었지요. 물론 이를 지원하기 위한 프로세서의 설계와 디자인도 큰 영향을 미치고 있습니다. 하지만 임베디드 시스템에는 아직까지 메모리를 자유롭게 사용할 만큼 풍부한 메모리 자원이 있지는 않습니다.

임베디드 시스템들은 특성상 여러 가지의 응용 프로그램을 한꺼번에 실행하는 것이 목적이 아닌 경우가 많습니다. 더욱이 임베디드 시스템에 사용되는 프로세서에서도 메모리 구조를 단순하게 구성하는 경우가 많습니다. 따라서 메모리가 작은 초기 버전의 임베디드 시스템용 운영체제들은 MMU (memory management unit)를 지원하지 않는 프로세서를 위한 메모리 관리를 축소한 형태의 임베디드 운영체제들이 있습니다. 또한 여러 가지 응용 프로그램의 사용을 제한하고, 가상 메모리 시스템을 포기하는 형태의 운영체제도 있습니다. 멀티태스킹이나 프로세싱을 지원하지 않는 운영체제들의 경우 대개가 이러한 형태입니다.


윈도우 시스템과 그래픽 환경
그래픽 환경은 임베디드 시스템에서 크게 필요하지 않다고 생각하기 쉽습니다. 하지만 사용자의 인터페이스 장비로 키보드나 마우스와 같은 장치를 사용하기 힘들고 대개 터치패드의 형태를 가지고 있기 때문에, GUI를 필요로 하는 시스템이 많습니다. 대개 UI를 지원하기 위한 서브 시스템은 라이브러리 형태를 사용하고 있습니다. 마이크로-윈도우라는 라이브러리 등을 사용하여 작은 메모리를 사용하면서도 훌륭한 시각적 효과를 얻을 수 있는 방식을 가지고 있습니다.