사용자:苦笑/작업장1

위키백과, 우리 모두의 백과사전.

실시간 운영체제 (줄여서 RTOS) 는 실시간 응용프로그램을 위해 개발된 운영 체제 (줄여서 OS) 이다. 이러한 운영체제는 응용프로그램의 처리요청을 거의 실시간으로 처리해 준다. 실시간 운영 체제는 프로그래머가 프로세서의 우선순위를 넘어서는 제어권을 제공한다. 응용프로그램의 프로세스 우선순위는 그 시스템 프로세스의 우선 순위를 초과 할 수 있다. 실시간 운영체제는 시스템 코드의 [크리티컬 섹션]을 최소화 하였기 때문에, 응용프로그램의 서비스 요청은 대단히 중요하게 취급된다.

실시간 운영체제의 핵심 사항은 응용프로그램의 테스크를 처리하여 끝마치는데 걸리는 시간을 일관되게 유지할 수 있는 정도에 있다. 시간의 변동폭은 지터(jitter)라 부른다. 경성(hard) 실시간 운영체제는 연성(soft) 실시간 운영체제에 비해 지터가 적다. 실시간 운영체제는 높은 수준의 스루풋(throughput)을 목적으로 설계 되지 않으며. 대신 soft or hard performance category의 보장에 있다. A real-time OS that can usually or generally meet a deadline is a soft real-time OS, but if can meet a deadline deterministically it is a hard real-time OS.

실시간 운영체제는 스케줄링에 향상된 알고리즘을 사용한다. Scheduler flexibility enables a wider, computer-system orchestration of process priorities, but real-time operating systems are more frequently dedicated to a narrow set of applications. Key factors in an real-time OS are a minimal interrupt latency and a minimal thread switching latency, but a real-time OS is valued more for how quickly or how predictably it can respond than for the amount of work it can perform in a given period of time.

설계 방식[편집]

2개의 기본적인 설계 방식이 존재한다:

  • 이벤트 드라이븐(Event-driven) 방식은 태스크(task)의 전환이 현재 수행중인 태스크보다 높은 우선순위를 갖는 이벤트가 서비스를 요청할 경우에 일어난다. 우선순위 기반 스케줄링이나 선점형 스케줄링 which switches tasks only when an event of higher priority needs service, called preemptive priority, or priority scheduling.
  • 시분할(Time-sharing) 스케줄링 방식은 클럭 인터럽트나 라운드 로빈과 같은 주기적인 이벤트가 발생할 때 태스크의 전환이 일어난다.

엄밀히 말해, 시분할 스케줄링 방식은 실제 필요한 것보다 더 자주 태스크 전환이 일어난다. 하지만 좀 더 자연스럽고, 예측하기 쉬운 멀티태스킹을 제공하며, 한개의 프로세스나 한명의 사용자가 혼자서 장치를 독점적으로 사용하는 것과 같은 효과를 제공한다. 초기의 CPU 설계들은 태스크를 전환하는데 여러 사이클이 필요했다. 태스크를 전환하는 동안 CPU는 . 그래서 초기의 운영체제들은 필요없는 태스크 전환을 배제하여 CPU가 대기하는 시간을 최소화 하도록 설계 되었다. 때문에 최근의 실시간 운영체제는 시분

스케줄링[편집]

일반적인 설계 방식에서, 한개의 태스크는 3가지 상태(states)가 존재한다: 1) running, 2) ready, 3) blocked. 대부분의 태스크는 blocked 로 대부분의 시간을 보낸다. CPU 1개당 오로지 1개의 태스크만이 running 상태로 존재한다. In simpler systems, the ready list is usually short, two or three tasks at most.

대게 스케줄러 대기 태스크 목록의 데이터 구조은 스케줄러의 임계 구역에서 worst-case 시간를 최소화 할 수 있도록 설계 된다. during which preemption is inhibited, and, in some cases, all interrupts are disabled. 하지만, 데이터 구조의 선택은 대기 리스트에 들어갈 수 있는 최대 태스크의 숫자에도 좌우된다.

만약 대기 목록에 적은수에 태스크만 존재하는 구조라면, 이중 연결 리스트 구조로 대기 목록을 구현 하는 것이 효율적이다. 통상 적은 수에 태스크만 존재하지만 가끔 그보다 많은 수가 존재하는 경우라면, 태스크를 실행할때 마다 전체 목록을 뒤져 우선순위가 높은 태스크를 찾는 작업을 반목적으로 하지 않도록 우선순위를 기준으로 미리 정렬하거나 높은 우선순위의 태스크를 낮은 우선순위의 태스크보다 먼저 대기 리스트에 추가한다. Care must be taken not to inhibit preemption during this entire search; the otherwise-long critical section should probably be divided into small pieces, so that if, during the insertion of a low priority task, an interrupt occurs that makes a high priority task ready, that high priority task can be inserted and run immediately before the low priority task is inserted.

플라이백(flyback) 시간이라고도 불리는 critical 응답 시간 is the time it takes to queue a new ready task and restore the state of the highest priority task to running. In a well-designed RTOS, readying a new task will take 3 to 20 instructions per ready-queue entry, and restoration of the highest-priority ready task will take 5 to 30 instructions.

좀더 발전된 실시간 운영체제에서는 실시간으로 동작하는 태스크들이 실시간으로 동작하지 않는 태스크들과 컴퓨터 자원을 공유한다. 따라서 대기 리스트는 매우 길어 질수있다. 이러한 시스템에서 스케줄러 대기 리스트를 단순히, 연결 리스트(linked list)로 구현하는 것은 알맞지 않다.

알고리즘[편집]

실시간 운영체제에서 주로 사용되는 스케줄링 알고리즘들:

태스크간 통신과 자원 공유(Intertask communication and resource sharing)[편집]

멀티태스킹 시스템은 여러개의 태스크 사이에 공유되는 데이터와 하드웨어 자원을 관리해주어야 한다. 대부분의 경우 두 개 이상의 태스크가 동시에 같은 데이터나 하드웨어 자원에 접근하는 것은 "위험"하다. ("위험"하다는 것은 한 태스크가 복수의 데이터를 갱신하는 중일 경우, 결과가 일관성이 없고 예측 불가능하다는 뜻이다. 다른 태스크가 이 데이터들에 접근해도 되는 시점은 갱신이 시작하기 전이나 완전히 종료된 후 뿐이다.) 이 문제를 해결하기 위해서 보통 사용되는 3가지 방식을 소개한다:

일시적인 인터럽트 비활성화[편집]

범용 운영체제에서는 사용자가 인터럽트를 마스크(비활성화)하지 못한다. 그 이유는 사용자의 프로그램이 운영체제의 핵심 자원인 CPU를 너무 긴 시간동안 점유 하고 있을 수 있기 때문이다. 다시 말해, 현재 사용되는 대다수의 CPU들은 유저 모드 코드가 인터럽트를 비활성화 할 수 있는 권한을 부여하지 않는다. 하지만, 많은 임베디드 시스템과 실시간 운영체제들은 응용프로그램이 운영체제의 간섭 없이 시스템 콜을 효율적으로 사용할 수 있게 하기 위해 커널 모드에서도 동작 할 수 있도록 한다.

단일 프로세서 시스템에서, 만약 응용프로그램이 현재 커널 모드로 동작하고, 인터럽트를 비활성화 시킬 수 있다면, 대게 인터럽트 비활성화야 말로 두개 이상의 태스크가 동시에 공유자원에 접근하는 것을 막아주는 최고의 기법이다. 인터럽트가 비활성화 되어 있는 경우, 현재 돌고 있는 태스크는 다른 태스크나 입터럽트가 CPU를 제어할 수 없기 때문에 배타성 을 띄며, 따라서 임계 구역은 보호 된다. 태스크가 임계 구역에서 벗어 나게 되면, 대기중인 인터럽트가 있다면 실행 되도록 인터럽트를 다시 활성화 시켜야 한다. 일시적으로 인터럽트를 비활성화 하는 것은 임계 구역의 가장 긴 경로가 인터럽트 대기 시간보다 짧은 경우 유효한 전략이다. 그렇지 않다면 이 방법을 통하여 시스템의 최대 인터럽트 대기 시간을 증가 시킬 가능성이 있다. 따라서 임계 구역이 단지 몇개의 명령어로 이루어 졌거나, 반복구문을 포함하지 않은 경우 유효하다고 할 수 있다. This method is ideal for protecting hardware bit-mapped registers when the bits are controlled by different tasks.

바이너리 세마포어(Binary semaphores)[편집]

When the critical section is longer than a few source code lines or involves lengthy looping, an embedded/real-time algorithm must resort to using mechanisms identical or similar to those available on general-purpose operating systems, such as semaphores and OS-supervised interprocess messaging. Such mechanisms involve system calls, and usually invoke the OS's dispatcher code on exit, so they typically take hundreds of CPU instructions to execute, while masking interrupts may take as few as one instruction on some processors. But for longer critical sections, there may be no choice; interrupts cannot be masked for long periods without increasing the system's interrupt latency.

A binary semaphore is either locked or unlocked. When it is locked, tasks must wait for the semaphore. Typically a task can set a timeout on its wait for a semaphore. There are several well-known problems with semaphore based designs such as priority inversion and deadlocks.

In priority inversion, a high priority task waits because a low priority task has a semaphore. A typical solution is to have the task that owns a semaphore run at (inherit) the priority of the highest waiting task. But this simplistic approach fails when there are multiple levels of waiting: A waits for a binary semaphore locked by B, which waits for a binary semaphore locked by C. Handling multiple levels of inheritance without introducing instability in cycles is complex.

In a deadlock, two or more tasks lock semaphores and then wait forever (that is, no timeout) for other the other task's semaphore, creating a cyclic dependency graph. The simplest deadlock scenario occurs when two tasks lock two semaphores in lockstep, but in the opposite order. Deadlock is usually prevented by careful design, or by having floored semaphores (which pass control of a semaphore to the higher priority task on defined conditions).

메시지 전달(Message passing)[편집]

자원 공유를 위한 다른 접근법은 태스크가 약속된 메시지 전달을 하도록 하는 것이다. 이 방식에서는 컴퓨터의 자원이 오직 한개의 태스크에 의해서 직접 제어된다. 만약 다른 태스크가 자원의 정보를 얻거나 제어하고 싶을 경우, 태스크는 자원을 제어하고 있는 태스크에게 메시지를 보낸다. Although their real-time behavior is less crisp than semaphore systems, simple message-based systems avoid most protocol deadlock hazards, and are generally better-behaved than semaphore systems. In particular, a queue entry is the entire resource consumed by a waiting service request. However, problems like those of semaphores are possible: Priority inversion can occur when a task is working on a low-priority message, and ignores a higher-priority message (or a message originating indirectly from a high priority task) in its incoming message queue. Protocol deadlocks can occur when two or more tasks wait for each other to send response messages.

인터럽트 핸들러와 스케줄러(Interrupt handlers and the scheduler)[편집]

인터럽트 핸들러가 실행중인 가장 높은 우선 순위의 태스크를 중단 시키기 때문에. from running, and since real time operating systems are designed to keep thread latency to a minimum, interrupt handlers are typically kept as short as possible. 인터럽트 핸들러는 하드웨어와의 상호작용을 가능한 뒤로 미룬다; 일반적으로 말해, typically all that is necessary is to acknowledge or disable the interrupt (인터럽트 핸들러가 반환된 후에 재발하지 않도록 ). The interrupt handler then queues work to be done at a lower priority level, often by unblocking a driver task (through releasing a semaphore or sending a message). 스케줄러는 종종 인터럽트 핸들러로 인하여 태스크가 블록 상태로 빠진것을 해지 할 수 있는 기능을 제공한다.

An OS maintains catalogs of objects it manages, such as threads, mutexes, memory, and so on. Updates to this catalog must be strictly controlled. For this reason it can be problematic when an interrupt handler call an OS function while the application is in the act of also doing so. The OS function called from an interrupt handler can find the object database to be in an inconsistent state because of the application's update. In general there are two major approaches to deal with this problem: the unified architecture and the segmented architecture. RTOSs implementing the unified architecture solve the problem by simply disabling interrupts while the internal catalog is updated. The downside of this is that interrupt latency increases, potentially losing interrupts. The segmented architecture does not make direct OS calls but delegates the OS related work to a separate handler. This handler runs at a higher priority than any thread but lower than the interrupt handlers. The advantage of this architecture is that the RTOS adds very few cycles to interrupt latency. As a result, OSes which implement the segmented architecture are more predictable and can deal with higher interrupt rates compared to RTOSs implementing the unified architecture.

동적 메모리 할당[편집]

실시간 운영체제의 동적 메모리 할당은 일반 OS보다 엄격한 조건이 요구된다.

우선, 할당 속도가 중요하다. 표준 메모리 할당 방식은 알맞은 크기의 사용되지 않는 메모리 블록을 찾기 위해서 연결 리스트를 검색하는 것이다. 하지만, 이 방식은 정해진 시간 안에 메모리 할당이 일어나야 하는 실시간 운영체제에는 맞지 않는다.

또한, 메모리의 공간을 분할하여 사용하 보면 단편화(Fragmentation)가 발생한다. 따라서 메모리 자체는 충분하더라도 메모리를 확보할 수 없어, 프로그램이 멈추는 현상이 발생할 가능성이 있다. 데스크탑 컴퓨터에서는 자주 재부팅하기 때문에 어느 정도의 단편화가 문제가 되지 않을 수 있다. 그러나 임베디드 시스템은 몇 년 동안 재부팅하지 않고 동작하는 경우도 있으므로, 단편화가 허용될 수 없다.

간단한 임베디드 시스템에서는 단순한 고정 크기 블록 알고리즘도 잘 동작 한다.

좀더 자세한 내용은 메모리 할당을 참조.

[편집]

An early example of a large-scale real-time operating system was the Transaction Processing Facility developed by American Airlines and IBM for the Sabre Airline Reservations System.

Currently the best known, most widely deployed, real-time operating systems are [출처 필요]

See the list of real-time operating systems for a comprehensive list. Also, see the list of operating systems for all types of operating systems.

같이 보기[편집]

References[편집]


틀:Real-time operating systems ko:실시간 운영 체제