chapter 06 rtos 에 대한 소개

37
Chapter 06 RTOS 에 에에 에에 6.1 에에에에 에에에 에에 6.2 에에에에 에에에 6.3 에에에에에 에에 에에에

Upload: elu

Post on 09-Jan-2016

167 views

Category:

Documents


8 download

DESCRIPTION

Chapter 06 RTOS 에 대한 소개. 6.1 태스크와 태스크 상태 6.2 태스크와 데이터 6.3 세마포어와 공유 데이터. RTOS 의 특징. 임베디드 시스템에서는 데스크 탑과는 달리 응용 프로그램과 RTOS 를 결합 시스템 부팅 시 , 응용 프로그램이 먼저 제어를 하고 난 후 RTOS 를 실행 애플리케이션과 RTOS 는 서로 밀접 하게 결합 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Chapter 06  RTOS 에 대한 소개

Chapter 06 RTOS 에 대한 소개

6.1 태스크와 태스크 상태

6.2 태스크와 데이터

6.3 세마포어와 공유 데이터

Page 2: Chapter 06  RTOS 에 대한 소개

2

RTOS 의 특징 임베디드 시스템에서는 데스크 탑과는 달리 응용 프로그램과 RTOS

를 결합 시스템 부팅 시 , 응용 프로그램이 먼저 제어를 하고 난 후 RTOS 를 실행

애플리케이션과 RTOS 는 서로 밀접 하게 결합

현재 동향 : Windows CE 나 임베디드 리눅스 처럼 데스크탑과 유사해지고 있음 . 제어방식이나 프로그래밍 방식도 데스크탑과 유사해지고 있음 ( 역자주 )

사용자 애플리케이션으로부터 운영체제를 완벽하게 보호하지 못 함

애플리케이션이 필요로 하는 RTOS 기능만 포함 대부분의 경우 프로그래밍시 RTOS 를 애플리케이션과 함께 컴파일 됨

특별한 분야를 제외하고 임베디드 리눅스와 윈도우 CE 로 바뀌는 추세임

Page 3: Chapter 06  RTOS 에 대한 소개

3

6.1 태스크와 태스크 상태 RTOS 로 작성되는 소프트웨어의 가장 기본적인 단위는 태스크 (Task)

임 RTOS 에서 태스크의 상태

실행 (Running) 마이크로프로세서가 태스크의 명령어를 수행하고 있는 상태 시스템이 여러 개의 프로세서들을 가지고 있지 않는 한 , 하나의 마이크로

프로세서가 존재하기 때문에 , 어느 주어진 순간엔 하나의 태스크가 실행된다 .

준비 (Ready)

현재 다른 태스크가 동작 중이지만 , 마이크로프로세서를 점유하면 당장 실행될 수 있는 상태 ( 마이크로프로세서를 제외한 모든 필요한 자원을 확보한 상태 )

여러 태스크가 준비 상태로 대기하고 있을 수 있음

Page 4: Chapter 06  RTOS 에 대한 소개

4

태스크와 태스크 상태 RTOS 로 작성되는 소프트웨어의 가장 기본적인 단위는 Task 임

대부분의 RTOS 에서 태스크는 단순히 서브루틴이다

Task 의 상태

1. 실행 (Running): 현재 실행중인 Task

2. 준비 (Ready): 마이크로 프로세서만 확보된다면 , 언제든지 실행 가능한 Task

3. 대기 (Blocked): 마이크로 프로세스를 확보해도 당장 실행할 수 없는 Task

E.g. 외부 이벤트가 발생하기를 기다리는 Task

기타 Suspended, Pended, Waiting, Dormant, Delayed 등의 상태는 Ready 또는 Blocked 의 세부 상태로 볼 수 있다 .

Page 5: Chapter 06  RTOS 에 대한 소개

5

스케줄러 태스크의 상태를 관리하고 어떤 태스크가 실행 상태로 되어야 하는 지를

결정 일반적인 데스크 탑 OS 에 비해서 상당히 단순한 전략을 사용

Page 6: Chapter 06  RTOS 에 대한 소개

6

태스크의 상태 전이도

Page 7: Chapter 06  RTOS 에 대한 소개

7

RTOS 와 함께하는 일반적인 질문 1 스케줄러는 태스크가 대기 상태인지 아닌지를 어떻게 알 수 있을까 ?

RTOS 는 태스크가 스케줄러에게 어떤 이벤트가 일어나기를 기다리고 있고 , 이벤트가 일어나서 시그널을 보내려고 한다는 것을 알려주는 여러 종류의 함수를 제공한다 .

Page 8: Chapter 06  RTOS 에 대한 소개

8

RTOS 와 함께하는 일반적인 질문 2 모든 태스크들이 대기 상태면 어떤 일이 발생하는가 ?

모든 태스크들이 대기 상태이면 , 스케줄러는 어떤 일이 발생하기를 기다리면서 RTOS 안에 있는 짧은 루프를 계속 돌 것이다 . 영원히 아무런 일이 발생하지 않는다면 이것은 프로그래머의 책임이다 .

프로그래머는 태스크가 대기 상태에서 빠져 나오기 위해서 RTOS 를 호출하는 인터럽트 루틴을 첨가 해야한다 .

Page 9: Chapter 06  RTOS 에 대한 소개

9

RTOS 와 함께하는 일반적인 질문 3 만약 우선 순위가 같은 두 개의 태스크가 모두 준비 상태이면 ?

RTOS 가 어떤 맵을 사용하는가에 따라 달라짐

1. 시스템이 같은 우선 순위를 갖는 태스크를 허용하지 않는다 .

2. 두 태스크 사이에서 시분할 이용

3. 한 태스크를 먼저 실행하고 , 이 태스크가 대기 상태가 되면 다른 태스크를 수행 – 어떤 RTOS 를 사용하는지에 따라 실행 순서는 달라짐

Page 10: Chapter 06  RTOS 에 대한 소개

10

RTOS 와 함께하는 일반적인 질문 4 만약 한 태스크가 실행되고 있을 때 , 우선 순위가 높은 다른 태스크가 대기

상태에서 빠져 나왔다면 , 현재 실행되고 있는 태스크는 바로 멈추고 대기 상태로 전환되는가 ?

Preemptive RTOS 는 더 높은 우선 순위의 태스크가 대기 상태에서 해제되자마자 낮은 우선 순위의 태스크를 정지 시킨다 .

Page 11: Chapter 06  RTOS 에 대한 소개

11

간단한 예제 – Sample Code/* 버튼 태스크 */void vButtonTask (void) /* 높은 우선 순위 */{

while (TRUE) {!! 사용자가 버튼을 누를 때까지 대기!! 사용자에게 바로 응답을 한다 .

}}

/* 레벨 태스크 */void vLevelTask (void) /* 낮은 우선 순위 */{

while (TRUE) {!! 탱크로부터 부표의 값을 읽는다 .!! 부표의 평균 값을 계산한다 .!! 약간의 지루한 계산을 한다 .!! 좀 더 지루한 계산을 한다 .!! 여전히 좀 더 지루한 계산을 한다 .

!! 다음에 어떤 탱크에 대해서 계산을 해야 하는지 결정한다 .}

}

Page 12: Chapter 06  RTOS 에 대한 소개

12

간단한 예제 – 버튼에 대한 응답

Page 13: Chapter 06  RTOS 에 대한 소개

13

간단한 예제 – 필요 기능 RTOS 의 편리한 점 중의 하나는 두 개의 태스크가 각각 서로 독립적으로

작성될 수 있고 , 시스템은 각각에 대해서 여전히 응답을 잘 한다는 것이다 .

앞의 코드가 재대로 동작하기 위해서는 각각의 태스크가 서버 루틴이라는 것과 태스크 사이의 우선 순위를 알려줘야 한다 . – 주로 RTOS 의 초기화 코드에 포함 한다 .

Page 14: Chapter 06  RTOS 에 대한 소개

14

간단한 예제 – RTOS 초기화 코드void main (void){

/* RTOS 를 초기화시킨다 ( 하지만 아직 실행은 안 시킨다 ). */InitRTOS ();

/* 사용할 태스크에 대해서 RTOS 에게 알려준다 . */StartTask (vRespondToButton, HIGH_PRIORITY);StartTask (vCalculateTankLevels, Low_PRIORITY);

/* RTOS 를 시작한다 ( 이 함수는 절대로 복귀하지 않는다 ). */StartRTOS ();

}

Page 15: Chapter 06  RTOS 에 대한 소개

15

태스크와 데이터 각각의 태스크는 레지스터 값들 , 프로그램 카운터 , 스택 등을 포함하는 고유의

컨텍스트 (Context) 를 가짐 – 비공유 자원

고유 컨텍스트를 제외한 다른 글로벌 변수 , 정적 변수 , 초기화된 변수 , 초기화 되지 않은 변수 , 등의 다른 데이터들은 시스템의 태스크 사이에서 공유 됨

태스크 사이의 데이터 이동

태스크들 사이에서 데이터 공유를 통해 가능

즉 , 두 태스크가 동일한 변수에 접근하면 됨

데이터 공유 방법

두 개 이상의 태스크가 동일한 변수에 접근 (변수가 선언된 동일한 모듈 내부에 태스크가 존재하는 경우 )

한 태스크에 선언된 변수를 extern 키워드를 사용해 접근 (변수가 선언된 모듈과 다른 모듈에 태스크가 존재하는 경우 )

Page 16: Chapter 06  RTOS 에 대한 소개

16

RTOS 기반의 실시간 시스템에서의 데이터

Page 17: Chapter 06  RTOS 에 대한 소개

17

태스크와 데이터 - 재진입 문제 재진입

어떤 태스크 수행도중 , RTOS 에 의해서 다른 태스크가 수행된 다음 다시 원래 태스크 수행을 위해서 제어를 복귀하는 것

재진입 가능한 태스크와 다른 태스크 사이에서 단순히 변수가 공유된다면 , 인터럽트 서비스 루틴과 태스크 코드 사이에서 발생됐던 것과 동일한 ‘공유 데이터’ 문제가 발생함

Page 18: Chapter 06  RTOS 에 대한 소개

18

태스크와 데이터 –재진입 여부를 결정하기 위한 세가지 규칙 재진입이 가능한 함수는 사용하는 함수들을 그 함수를 호출한

태스크의 스택에 저장하거나 그 태스크에서만 변수를 사용하는 경우를 제외하고는 , 아토믹하지 않은 방법으로는 변수들을 사용하지 않는다 .

재진입이 가능한 함수는 재진입이 가능하지 않은 어떠한 함수도 호출 하지 않아야 함

재진입이 가능한 함수는 아토믹하지 않은 방법으로 하드웨어를 사용하지 않음

Page 19: Chapter 06  RTOS 에 대한 소개

19

재진입 규칙의 적용 - 코드BOOL fError; /* 다른 곳에서 fError 의 값을 세팅한다 . */

void display (int j)

{

if(!fError) {

printf(“\nValue: %d”, j);j = 0;fError = TRUE;

} else {

printf (“\nCould not display value”);fError = FALSE;

}}

Page 20: Chapter 06  RTOS 에 대한 소개

20

재진입 규칙의 적용 - 문제 앞의 display 함수는 재진입 가능한가 ?

첫 번째 규칙 위반

fError 변수는 메모리에 고정된 위치에 있기 때문에 display 함수를 호출하는 태스크들 사이에서 공유될 수 있다 .

fError 변수의 값을 검사할 때와 변수의 값을 저장할 때의 시간 사이에서 RTOS 가 태스크를 전환할 수 있기 때문에 , fError 를 사용하는 것은 아토믹 하지 않다 .

두 번째 규칙의 위반

printf 함수의 경우 대부분 재진입이 가능하지만 , compiler 구현에 의존적임

재진입의 회색지대 : 컴파일러에 의존적인 공유 문제를 포함하는 코드

Page 21: Chapter 06  RTOS 에 대한 소개

21

세마포어와 공유 데이터 기차들은 세마포어로 두 가지 일을 수행한다 . 첫 째는 , 기차가 보호된

영역을 벗어 날 때 , 세마포어를 올린다 . 둘 째는 , 기차가 세마포어가 있는 곳 까지 왔을 때 , 세마포어가 올라갈 때 까지 기다리거나 , 세마포어가 올라와 있으면 통과하고 세마포어를 내린다 . RTOS 에 있는 일반적인 세마포어도 이와 같은 일을 한다 .

Page 22: Chapter 06  RTOS 에 대한 소개

22

세마포어와 공유 데이터 – 이진 세마포어 태스크들은 TakeSemaphore 와 ReleaseSemaphore 두 개의 함수를 호출

한번에 오직 한 태스크만 세마포어를 가질 수 있음

만일 한 태스크가 세마포어를 가지기 위해서 TakeSemaphore 를 호출하고 , 풀어주기 위한 ReleaseSemaphore 를 호출하지 않았다면 , 다른 태스크가 세마포어 영역으로 진입하기 위해서 TakeSemaphore 를 호출한다면 , 첫 번째 태스크가 ReleaseSemaphore 를 호출할 때까지 기다려야 함

Page 23: Chapter 06  RTOS 에 대한 소개

23

세마포어의 데이터보호 예제 - 1struct { long lTankLevel; long lTimeUpdated;} tankdata[MAX_TANKS];

/* 버튼 태스크 */void vRespondToButton (void){ /* 높은 우선순위 */ int i; while (TRUE) { !! 사용자가 버튼을 누를 때까지 대기한다 . i = !!눌려진 버튼의 아이디를 읽는다 . TakeSemaphore(); printf (“\nTime: %08ld LEVEL: %08ld”,

tankdata[i].lTimeUpdated,tankdata[i].lTankLevel);

ReleaseSemaphore (); }}

/* 레벨 태스크 */

void vCalculateTankLevels (void){ /* 낮은 우선순위 */ int I = 0; while (TRUE) { … TakeSemaphore (); !! tankdata[i].lTimeUpdated !! 값을 설정한다 . !! tankdata[i].lTankLevel 값을 !! 설정한다 . ReleaseSemaphore (); … }}

Page 24: Chapter 06  RTOS 에 대한 소개

24

세마포어의 데이터 보호 예제 - 2 ‘레벨 태스크’가 탱크의 구조체 데이터를 갱신하기 위해서 TakeSemaphore

() 를 호출하고 , tankdata[i].lTimeUpdated 를 설정하는 동안 , ‘버튼 태스크’를 수행하기 위해서 버튼을 누르는 경우의 이벤트 순서

1. RTOS 는 이전과 같이 레벨 태스크를 준비상태로 만들고 ‘버튼 태스크’로 전환

2. 버튼 태스크가 TakeSemaphore 를 호출해서 세마포어를 가지려하면 , 레벨 태스크가 이미 세마포어를 가지고 있기 때문에 , 세마포어가 풀어질 때까지 대기 상태로 진입

3. RTOS 가 실행할 태스크를 찾아보면 , 레벨 태스크가 준비 상태이고 , 버튼 태스크가 대기 상태이기 때문에 레벨 태스크가 실행이 되고 , 결국 레벨 태스크는 ReleaseSemaphore 를 이용해서 세마포어를 풀어준다 .

4. 세마포어가 해제되어 있기 때문에 , RTOS 는 버튼 태스크를 대기 상태에서 실행 상태로 상태를 전이 한다 .

Page 25: Chapter 06  RTOS 에 대한 소개

25

세마포어의 데이터 보호 예제 - 3

Page 26: Chapter 06  RTOS 에 대한 소개

26

세마포어와 공유 데이터 다중 세마포어

다중 세마포어를 사용하는 장점은 무엇일까 ? 태스크가 세마포어를 가질 때 마다 , 잠재적으로 같은 세마포어를

사용하는 다른 태스크의 응답이 느려진다 .

하나의 세마포어만 사용하는 시스템에서 , 가장 낮은 우선순위의 태스크가 온도들의 공유 배열에서 데이터를 변경하기 위해 세마포어를 가지고 있다면 , 가장 높은 우선순위의 태스크는 온도에 대해서는 신경 쓰지 않고 에러의 개수를 변경 시키려고 해도 , 그 세마포어를 기다려야만 한다 .

다른 종류의 세마포어는 다른 종류의 공유 자원에 대응할 수 있다 .

주의 사항 RTOS 는 어떤 Task 가 어떤 Semaphore 를 가지는지에 대해서는 관여하지 않는다 .

Page 27: Chapter 06  RTOS 에 대한 소개

27

세마포어와 공유 데이터 세마포어의 다른 용도 ( 공유자원 보호 외 )

한 태스크에서 다른 태스크로 또는 인터럽트 루틴에서 태스크로의 간단한 통신을 위한 수단

세마포어를 사용할 때 문제점들

세마포어를 가지는 것을 잊어 버린다 .

세마포어를 풀어 주는 것을 잊어 버린다 .

잘못된 세마포어를 가진다 .

너무 오랫동안 세마포어를 가지고 있는다 .

Page 28: Chapter 06  RTOS 에 대한 소개

28

세마포어와 공유데이터 – 우선 순위 역전 1 세 개의 Task A, B, C 가 존재

우선 순위는 A가 가장 높고 , 그 다음 B, C 순서이다 .

Task A와 C 는 동일한 세마포어를 참조하고 있다 .

문제

1. 현재 우선 순위가 가장 낮은 Task C 가 실행되는 동안 , Task B 가 발생했다 .

2. Task B 는 C 와 공유 세마포어가 없기 때문에 대기 상태에서 해제되고 , 실행된다 .

3. Task B 가 실행되는 동안 , 우선 순위가 가장 높은 Task A가 실행되고 , Task A는 C 가 가지고 있는 세마포어 때문에 더 이상 실행되지 못하고 , 대기 상태로 들어간다 . 이때 우선 순위가 낮은 Task C 는 Task B 에 의해서 Semaphore 를 해제하지 못한다 .

4. Task B 는 계속해서 실행된다 . – 우선 순위 역전 발생

우선 순위 계승 : 위와 같은 문제 발생시 일시적으로 Task C 를 A와 동일한 우선 순위로 일시적으로 변경해서 문제를 해결하는 방법

Page 29: Chapter 06  RTOS 에 대한 소개

29

세마포어와 공유 데이터 – 우선 순위 역전 2

Page 30: Chapter 06  RTOS 에 대한 소개

30

세마포어와 공유데이터 - 데드락int a;int b;

AMXID hSemaphoreA;AMXID hSemaphoreB;

void vTask1 (void) { ajsmrsv (hSemaphoreA,0,0); ajsmrsv (hSemaphoreB,0,0); a = b; ajsmrls (hSemaphoreB); ajsmrls (hSemaphoreA);}

void vTask2 (void) { ajsmrsv (hSemaphoreB,0,0); ajsmrsv (hSemaphoreA,0,0); a = b; ajsmrls (hSemaphoreA); ajsmrls (hSemaphoreB);}

여기서 RTOS 가 vTask2 로 작업 전환

Page 31: Chapter 06  RTOS 에 대한 소개

31

세마포어와 공유데이터 - 주의사항 세마포어를 사용하는 모든 경우는 버그가 발생하길 기다리는 것과

같다 .

따라서 , 프로그래머는 반드시 사용해야만 할 때 세마포어를 사용하고 , 피할 수 있으면 사용하지 말아야 한다 .

Page 32: Chapter 06  RTOS 에 대한 소개

32

세마포어와 공유 데이터 – 변형된 세마포어들

변형된 세마포어들

카운팅 세마포어 (Counting Semaphore)

여러 번 제공될 수 있는 세마포어 . 세마포어는 정수로 구성되고 , 세마포어를 얻을 때 1씩 감소하고 , 세마포어를 해제할 때 1씩 증가한다 . 만일 세마포어가 0이되면 더 이상 세마포어를 얻을 수 없고 대기 상태로 들어간다 . 세마포어의 원형이다 .

리소스 세마포어 (Resource Semaphore) 또는 리소스 (Resource)

세마포어를 획득한 태스크만이 세마포어를 해제할 수 있다 . 공유 문제 해결에는 적절하지만 , 두 태스크 사이의 통신을 위해서는 사용할 수 없다 .

뮤택스 세마포어 (Mutex Semaphore) 또는 뮤택스 (Mutex)

우선 순위 역전 문제를 자동적으로 해결할 수 있는 세마포어

Page 33: Chapter 06  RTOS 에 대한 소개

33

6.3 세마포어와 공유 데이터 – 공유 데이터 보호 공유 데이터를 보호하는 방법들

인터럽트를 금지시키는 것은 시스템의 모든 인터럽트 루틴과 다른 태스크들의 응답 시간에 영향을 끼치는 가장 극단적인 조치이다 .

데이터가 태스크 코드와 인터럽트 루틴 사이에서 공유 된다면 , 인터럽트 금지가 유일한 방법이다 .

이 방법은 빠르다 .

세마포어를 이용하는 것은 같은 세마포어를 원하는 태스크에만 영향을 미치기 때문에 , 데이터를 보호하는데 가장 정확한 방법이다 .

태스크 전환을 금지하는 방법은 어떤 면에서는 두 방법의 중간에 있다 . 이 방법은 인터럽트 루틴에는 전혀 영향을 끼치지 않지만 , 모든 다른 태스크의 응답은 정지 시킨다 .

Page 34: Chapter 06  RTOS 에 대한 소개

34

세마포어와 공유 데이터 – 공유 데이터 보호 공유 데이터 보호 방법

인터럽트를 금지 시키는 방법

세마포어를 사용하는 방법

태스크 전환을 금지 시키는 방법

Page 35: Chapter 06  RTOS 에 대한 소개

35

세마포어와 공유 데이터 – 비교 (1) 인터럽트 금지

모든 인터럽트와 다른 태스크 응답 시간에 영향을 미치는 극단적인 조치 ( 인터럽트 금지 시 스케줄러가 마이크로프로세서의 제어권을 가져올 수 없기 때문에 태스크 전환 역시 금지 됨 )

데이터가 ISR 과 태스크 코드 사이에 공유될 경우 공유 데이터를 보호하기 위한 유일한 방법

대부분의 프로세서에서 인터럽트 금지나 해제는 하나의 명령어로 처리된다 .

세마포어를 이용하는 방법 세마포어는 원하는 태스크에만 영향을 미치기 때문에 , 데이터를

보호하는데 가장 정확한 방법이다 .

어느 정도 마이크로 프로세서의 시간을 소비한다 .

인터럽트 루틴에는 적용할 수 없다 .

Page 36: Chapter 06  RTOS 에 대한 소개

36

세마포어와 공유 데이터 – 비교 (2) 태스크 전환을 금지하는 방법

앞의 두 방법의 중간 단계

인터럽트 루틴에는 전혀 영향을 끼치지 않지만 , 모든 다른 태스크의 응답은 정지 시킨다 .

Page 37: Chapter 06  RTOS 에 대한 소개

37

6 장 요약

일반적인 실시간 운영 체제 (RTOS) 는 데스크 탑의 운영 체제 보다 더 작고 더 적은 수의 서비스를 제공한다 . 그리고 , 좀더 응용프로그램에 밀착되어 있다 .

RTOS 는 다양한 제품을 살 수 있고 , 일반적으로 직접 작성하는 것보다 구입해서 사용하는 것이 합리적이다 .

태스크는 RTOS 환경에서 작성되는 소프트웨어의 기본 단위이다 . 각각의 태스크는 항상 세 가지의 상태를 가진다 . 실행 , 준비 , 대기 이다 . RTOS 에서의

스케줄러는 준비 상태의 태스크 중 가장 높은 우선순위의 태스크를 실행시킨다 . 각각의 태스크는 독자적인 스택을 가지고 있다 . 하지만 , 시스템의 다른 데이터는 모든

태스크간에 공유 된다 . 그러므로 , 공유 데이터 문제는 다시 등장할 수 있다 . 하나 이상의 태스크로부터 호출 되어도 잘 작동하는 함수는 재진입 가능한 함수라고 불린다 . 세마포어는 공유 데이터 문제를 해결할 수 있다 . 한번에 한 태스크만 세마포어를 가질 수

있기 때문에 , 세마포어는 공유 데이터를 버그로부터 지켜 준다 . 세마포어는 가지다 와 풀어주다 의 두 종류의 연관된 함수를 가진다 .

뮤택스 , 이진 세마포어 , 카운팅 세마포어는 RTOS 가 제공하는 일반 적인 세마포어 들의 종류들 이다 .

공유 데이터를 보호하는 세 가지 방법은 인터럽트 금지 , 세마포어 사용 , 태스크 전환 금지 이다 .