임베디드 OS 종류

스레드 기반 운영체제

  • 시스템(커널) 프로세스와 응용(사용자) 프로세스가 구분되지 않고 동일한 기준으로 수행
  • 응용 프로그램의 오류가 시스템 전체를 멈추게 할 수 있음
  • EX) VxWorks

    프로세스 기반 운영체제

  • 시스템 프로세스와 응용 프로세스가 별도의 기준으로 수행
  • 응용 프로그램의 오류가 시스템 프로세스의 동작에 영향을 미치지 않음
  • EX) 임베디드 리눅스


RTOS

임베디드 OS는 실시간 처리를 지원해야하는 경우가 많으므로 실시간 운영체제(RTOS)를 사용한다. 특징은 다음과 같다.

  • 선점형 멀티태스킹 지원
  • 각 태스크들은 우선 순위를 가지고 있어 높은 우선 순위를 가지는 태스크들이 먼저 실행되는 구조
  • 태스크들이 원하는 시간 안에 원하는 결과를 얻도록 보장

    RTOS 구성 요소

  • 스케줄러: RTOS의 핵심으로, 실시간성을 위해 태스크 관리에 따라 성능이 좌우됨
  • 인터럽트 처리: 프로세서 외부의 장치가 프로세서 사용을 요청하는 신호
  • 자원관리: 리소스가 제한된 임베디드 시스템에서 자원 활용 방법
  • 태스크: 스케줄러가 프로그램을 실행시키기 위한 일의 작은 단위, 태스크들의 관리, 우선순위 책정, 스케줄링 알고리즘 선정


스레드

RTOS는 스레드로 구성되어 있어 모든 태스크가 동일한 CPU 동작 방식을 가진다. 스레드는 CPU 이용의 기본 단위로 같은 프로세스에 속한 다른 스레드와 코드 등 OS 자원을 공유한다.

image


시스템 부팅

  • 컴퓨터가 구동을 시작하기 위해선 부트스트랩 프로그램(Bootstrap Program) 이라는 초기 프로그램이 적재됨
  • 이것은 펌웨어라고 알려져 있는 컴퓨터 내의 ROM(Read-Only Memory)나 EEPROM에 저장되어 있음
  • CPU 레지스터로부터 장치 제어기, 메모리 내용 등을 포함한 시스템의 모든 면을 초기화함
  • 부트 스트랩 프로그램은 운영체제의 커널을 찾아 메모리에 적재하고 수행을 시작함 -> 사용자에게 서비스 제공

    부트로더

    하드웨어 초기화, 커널 부팅, 명령 처리 등을 담당한다. 리눅스 커널 부팅 이전에 미리 실행되며 커널이 올바르게 부팅되기 위해 필요한 모든 관련 작업을 마무리하고 최종적으로 리눅스 커널을 부팅시킨다. 부트로더를 메모리에 올리는 과정이 부트스트랩이다.


CPU 스케줄링

임베디드 OS는 태스크라 불리는 프로그램 수행 단위를 가지게 된다. 대부분 복수 개의 태스크가 동시에 실행되는 환경을 가지며 OS 내부 스케줄러에 의해 다음 번에 실행되는 태스크를 선택한다. 실제 대부분은 우선 순위에 기반을 둔 스케줄링 알고리즘을 사용한다.

우선순위 알고리즘

CPU는 가장 높은 우선순위를 가진 프로세스에게 할당된다. 우선 순위가 같다면 선입선처리 순서로 스케줄된다.

FIFO

  • 동일한 우선순위를 가진 태스크 존재 시 먼저 시작한 태스크가 종료될 때까지 다음 번 수행된 태스크가 스케줄링을 받지 못하는 알고리즘

    라운드 로빈

  • 동일한 우선순위를 가진 태스크들이 존재할 경우 각각 미리 정해진 time slice만큼씩 차례로 스케줄링됨
  • time slice가 context-switching 시간보다 커야 함 image

선점형 커널(Preemptive Kernel)

어떤 태스크가 수행되고 있을 경우 커널이 강제로 그 태스크의 수행을 중지시키고 다른 태스크의 기능을 수행시키는 커널을 말한다.

  • 비선점형에 비해 Interrupt latency가 길어지는 단점
  • 우선 순위가 높은 태스크가 먼저 수행된다는 점에서 대부분의 임베디드 OS에서 사용
  • 커널의 안정성을 높게 유지실 수 있음
  • 답이 빠르며 실시간 프로세스가 현재 커널에서 실행 중인 프로세스를 선점할 수 있기 때문에 실시간 프로그래밍에 적합함


동기화

임계구역(Critical Section)

임계 구역 내에서는 다른 프로세스와 공유하는 변수를 변경하거나, 테이블을 갱신하거나 파일을 쓰거나 하는 등의 작업을 수행한다. 한 프로세스가 자신의 임계구역에서 수행하는 동안에는 다른 프로세스들은 그들의 임계구역에 들어갈 수 없다. 즉, 동시에 두 프로세스는 그들의 임계구역 안에서 실행할 수 없다.

임계구역 문제에 대한 해결안은 다음 세 가지 요구조건을 충족해야 한다.

  • 상호 배제(mutal exclusion): 프로세스가 자기의 임계구역에서 실행되면, 다른 프로세스는 그들 자신의 임계구역에서 실행될 수 없음
  • 진행(progress): 자신의 임계구역에서 실행되는 프로세스가 없고 그들 자신의 임계구역으로 진입하려는 프로세스들이 있다면, 나머지 구역에서 실행 중이지 않은 프로세스들만 다음에 누가 그 임계구역으로 진입할 수 있는 지를 결정하는 데 참여할 수 있으며, 이 선택은 무한정 연기될 수 없다.
  • 한정된 대기(bounded waiting): 프로세스가 자기의 임계구역에 진입하려는 요청을 한 후부터 그 요청이 허용될 때까지 다른 프로세스들이 그들 자신의 임계구역에 진입하도록 허용되는 횟수에 한계가 있어야 함

뮤텍스락

프로세스는 임계구역에 들어가기 전에 반드시 락을 획득해야 하고 임계구역을 빠져나올 때 락을 반환한다.

acquire()
{
    while (!available) {
    	; /* busy waiting */
    }
    available = false;
}

release()
{
    available = true;
}

프로세스가 임계구역에 있는 동안 임계구역에 들어가기 원하는 다른 프로세스들은 acquire() 함수를 호출하는 반복문을 계속 실행하는 바쁜 대기(busy waiting)을 해야 하는 단점이 있다.

세마포어(Semaphores)

mutex와 유사하게 동작하지만 프로세스들이 자신의 행동을 정교하게 동기화할 수 있다. 여러 개의 프로세스나 스레드가 임계구역에 진입할 수 있는 매커니즘이며, 카운터를 이용해 동시에 리소스에 접근할 수 있는 프로세스를 제한한다. 세마포어 S는 정수 변수로, 초기화를 제외하고 wait(), signal()로만 접근이 가능하다.

wait(S)
{
    while (S <= 0) {
    	; /* busy waiting */
    }
    S--;
}

signal(S)
{
    S++;
}

카운팅 세마포어는 유한한 개수를 가진 자원에 대한 접근을 제어하는 데 사용된다. 세마포어는 가용한 자원의 개수로 초기화된다.

  • 자원을 사용하고자 하는 프로세스는 wait() 연산을 수행하고, 세마 포어 값은 감소
  • 프로세스가 자원을 방출할 때 signal() 연산을 수행하고 세마포어 증가
  • 세마포어 값이 0인 경우 모든 자원은 사용 중 -> 자원을 사용하고자 하면 세마포어가 0보다 커질 때까지 봉쇄됨

    데드락(deadlock)

    프로세스 A는 B가 종료될 때까지 대기하고, 프로세스 B는 A가 종료될 때까지 기다리는 경우와 같이 두 프로세스가 리소스를 점유하고 놓아주지 않거나, 어떠한 프로세스도 리소스를 점유하지 못하는 상태가 되어 프로그램이 멈추는 현상이다. 한 집합 내의 모든 프로세스들이 그 집합 내의 다른 프로세스만이 유발할 수 있는 사건을 기다리고 있을 때, 데드락에 있다고 한다.


Reference