1 / 37

Chapter 06 RTOS 에 대한 소개

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

elu
Download Presentation

Chapter 06 RTOS 에 대한 소개

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 06 RTOS에 대한 소개 6.1 태스크와 태스크 상태 6.2 태스크와 데이터 6.3 세마포어와 공유 데이터

  2. RTOS의 특징 • 임베디드 시스템에서는 데스크 탑과는 달리 응용 프로그램과 RTOS를 결합 • 시스템 부팅 시, 응용 프로그램이 먼저 제어를 하고 난 후 RTOS를 실행 • 애플리케이션과 RTOS는 서로 밀접 하게 결합 • 현재 동향: Windows CE나 임베디드 리눅스 처럼 데스크탑과 유사해지고 있음. 제어방식이나 프로그래밍 방식도 데스크탑과 유사해지고 있음(역자주) • 사용자 애플리케이션으로부터 운영체제를 완벽하게 보호하지 못 함 • 애플리케이션이 필요로 하는 RTOS 기능만 포함 • 대부분의 경우 프로그래밍시 RTOS를 애플리케이션과 함께 컴파일 됨 • 특별한 분야를 제외하고 임베디드 리눅스와 윈도우 CE로 바뀌는 추세임

  3. 6.1 태스크와 태스크 상태 • RTOS로 작성되는 소프트웨어의 가장 기본적인 단위는 태스크(Task) 임 • RTOS에서 태스크의 상태 • 실행(Running) • 마이크로프로세서가 태스크의 명령어를 수행하고 있는 상태 • 시스템이 여러 개의 프로세서들을 가지고 있지 않는 한, 하나의 마이크로 프로세서가 존재하기 때문에, 어느 주어진 순간엔 하나의 태스크가 실행된다. • 준비(Ready) • 현재 다른 태스크가 동작 중이지만, 마이크로프로세서를 점유하면 당장 실행될 수 있는 상태(마이크로프로세서를 제외한 모든 필요한 자원을 확보한 상태) • 여러 태스크가 준비 상태로 대기하고 있을 수 있음

  4. 태스크와 태스크 상태 • RTOS로 작성되는 소프트웨어의 가장 기본적인 단위는 Task임 • 대부분의 RTOS에서 태스크는 단순히 서브루틴이다 • Task의 상태 • 실행(Running): 현재 실행중인 Task • 준비(Ready): 마이크로 프로세서만 확보된다면, 언제든지 실행 가능한 Task • 대기(Blocked): 마이크로 프로세스를 확보해도 당장 실행할 수 없는 Task • E.g. 외부 이벤트가 발생하기를 기다리는 Task • 기타 Suspended, Pended, Waiting, Dormant, Delayed 등의 상태는 Ready 또는 Blocked의 세부 상태로 볼 수 있다.

  5. 스케줄러 • 태스크의 상태를 관리하고 어떤 태스크가 실행 상태로 되어야 하는 지를 결정 • 일반적인 데스크 탑 OS에 비해서 상당히 단순한 전략을 사용

  6. 태스크의 상태 전이도

  7. RTOS와 함께하는 일반적인 질문 1 • 스케줄러는 태스크가 대기 상태인지 아닌지를 어떻게 알 수 있을까? • RTOS는 태스크가 스케줄러에게 어떤 이벤트가 일어나기를 기다리고 있고, 이벤트가 일어나서 시그널을 보내려고 한다는 것을 알려주는 여러 종류의 함수를 제공한다.

  8. RTOS와 함께하는 일반적인 질문 2 • 모든 태스크들이 대기 상태면 어떤 일이 발생하는가? • 모든 태스크들이 대기 상태이면, 스케줄러는 어떤 일이 발생하기를 기다리면서 RTOS 안에 있는 짧은 루프를 계속 돌 것이다. 영원히 아무런 일이 발생하지 않는다면 이것은 프로그래머의 책임이다. • 프로그래머는 태스크가 대기 상태에서 빠져 나오기 위해서 RTOS를 호출하는 인터럽트 루틴을 첨가 해야한다.

  9. RTOS와 함께하는 일반적인 질문 3 • 만약 우선 순위가 같은 두 개의 태스크가 모두 준비 상태이면? • RTOS가 어떤 맵을 사용하는가에 따라 달라짐 • 시스템이 같은 우선 순위를 갖는 태스크를 허용하지 않는다. • 두 태스크 사이에서 시분할 이용 • 한 태스크를 먼저 실행하고, 이 태스크가 대기 상태가 되면 다른 태스크를 수행 –어떤 RTOS를 사용하는지에 따라 실행 순서는 달라짐

  10. RTOS와 함께하는 일반적인 질문 4 • 만약 한 태스크가 실행되고 있을 때, 우선 순위가 높은 다른 태스크가 대기 상태에서 빠져 나왔다면, 현재 실행되고 있는 태스크는 바로 멈추고 대기 상태로 전환되는가? • Preemptive RTOS는 더 높은 우선 순위의 태스크가 대기 상태에서 해제되자마자 낮은 우선 순위의 태스크를 정지 시킨다.

  11. 간단한 예제 – Sample Code /* 버튼 태스크 */void vButtonTask (void) /* 높은 우선 순위 */{ while (TRUE) { !! 사용자가 버튼을 누를 때까지 대기!! 사용자에게 바로 응답을 한다. }} /* 레벨 태스크 */void vLevelTask (void) /* 낮은 우선 순위 */{ while (TRUE) { !! 탱크로부터 부표의 값을 읽는다. !! 부표의 평균 값을 계산한다. !! 약간의 지루한 계산을 한다. !! 좀 더 지루한 계산을 한다. !! 여전히 좀 더 지루한 계산을 한다. !! 다음에 어떤 탱크에 대해서 계산을 해야 하는지 결정한다. }}

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

  13. 간단한 예제 –필요 기능 • RTOS의 편리한 점 중의 하나는 두 개의 태스크가 각각 서로 독립적으로 작성될 수 있고, 시스템은 각각에 대해서 여전히 응답을 잘 한다는 것이다. • 앞의 코드가 재대로 동작하기 위해서는 각각의 태스크가 서버 루틴이라는 것과 태스크 사이의 우선 순위를 알려줘야 한다. –주로 RTOS의 초기화 코드에 포함 한다.

  14. 간단한 예제 – RTOS 초기화 코드 void main (void){ /* RTOS를 초기화시킨다(하지만 아직 실행은 안 시킨다). */ InitRTOS (); /* 사용할 태스크에 대해서 RTOS에게 알려준다. */ StartTask (vRespondToButton, HIGH_PRIORITY); StartTask (vCalculateTankLevels, Low_PRIORITY); /* RTOS를 시작한다 (이 함수는 절대로 복귀하지 않는다). */ StartRTOS (); }

  15. 태스크와 데이터 • 각각의 태스크는 레지스터 값들, 프로그램 카운터, 스택 등을 포함하는 고유의 컨텍스트(Context)를 가짐 –비공유 자원 • 고유 컨텍스트를 제외한 다른 글로벌 변수, 정적 변수, 초기화된 변수, 초기화 되지 않은 변수, 등의 다른 데이터들은 시스템의 태스크 사이에서 공유 됨 • 태스크 사이의 데이터 이동 • 태스크들 사이에서 데이터 공유를 통해 가능 • 즉, 두 태스크가 동일한 변수에 접근하면 됨 • 데이터 공유 방법 • 두 개 이상의 태스크가 동일한 변수에 접근 (변수가 선언된 동일한 모듈 내부에 태스크가 존재하는 경우) • 한 태스크에 선언된 변수를 extern 키워드를 사용해 접근 (변수가 선언된 모듈과 다른 모듈에 태스크가 존재하는 경우)

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

  17. 태스크와 데이터 - 재진입 문제 • 재진입 • 어떤 태스크 수행도중, RTOS에 의해서 다른 태스크가 수행된 다음 다시 원래 태스크 수행을 위해서 제어를 복귀하는 것 • 재진입 가능한 태스크와 다른 태스크 사이에서 단순히 변수가 공유된다면, 인터럽트 서비스 루틴과 태스크 코드 사이에서 발생됐던 것과 동일한 ‘공유 데이터’ 문제가 발생함

  18. 태스크와 데이터 –재진입 여부를 결정하기 위한 세가지 규칙 • 재진입이 가능한 함수는 사용하는 함수들을 그 함수를 호출한 태스크의 스택에 저장하거나 그 태스크에서만 변수를 사용하는 경우를 제외하고는, 아토믹하지 않은 방법으로는 변수들을 사용하지 않는다. • 재진입이 가능한 함수는 재진입이 가능하지 않은 어떠한 함수도 호출 하지 않아야 함 • 재진입이 가능한 함수는 아토믹하지 않은 방법으로 하드웨어를 사용하지 않음

  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; }}

  20. 재진입 규칙의 적용 - 문제 • 앞의 display 함수는 재진입 가능한가? • 첫 번째 규칙 위반 • fError 변수는 메모리에 고정된 위치에 있기 때문에 display 함수를 호출하는 태스크들 사이에서 공유될 수 있다. • fError 변수의 값을 검사할 때와 변수의 값을 저장할 때의 시간 사이에서 RTOS가 태스크를 전환할 수 있기 때문에, fError를 사용하는 것은 아토믹 하지 않다. • 두 번째 규칙의 위반 • printf 함수의 경우 대부분 재진입이 가능하지만, compiler 구현에 의존적임 • 재진입의 회색지대: 컴파일러에 의존적인 공유 문제를 포함하는 코드

  21. 세마포어와 공유 데이터 • 기차들은 세마포어로 두 가지 일을 수행한다. 첫 째는, 기차가 보호된 영역을 벗어 날 때, 세마포어를 올린다. 둘 째는, 기차가 세마포어가 있는 곳 까지 왔을 때, 세마포어가 올라갈 때 까지 기다리거나, 세마포어가 올라와 있으면 통과하고 세마포어를 내린다. RTOS에 있는 일반적인 세마포어도 이와 같은 일을 한다.

  22. 세마포어와 공유 데이터 –이진 세마포어 • 태스크들은 TakeSemaphore와 ReleaseSemaphore 두 개의 함수를 호출 • 한번에 오직 한 태스크만 세마포어를 가질 수 있음 • 만일 한 태스크가 세마포어를 가지기 위해서 TakeSemaphore를 호출하고, 풀어주기 위한 ReleaseSemaphore를 호출하지 않았다면, 다른 태스크가 세마포어 영역으로 진입하기 위해서 TakeSemaphore를 호출한다면, 첫 번째 태스크가 ReleaseSemaphore를 호출할 때까지 기다려야 함

  23. 세마포어의 데이터보호 예제 - 1 struct { 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 ();… }}

  24. 세마포어의 데이터 보호 예제 - 2 • ‘레벨 태스크’가 탱크의 구조체 데이터를 갱신하기 위해서 TakeSemaphore()를 호출하고, tankdata[i].lTimeUpdated를 설정하는 동안, ‘버튼 태스크’를 수행하기 위해서 버튼을 누르는 경우의 이벤트 순서 • RTOS는 이전과 같이 레벨 태스크를 준비상태로 만들고 ‘버튼 태스크’로 전환 • 버튼 태스크가 TakeSemaphore를 호출해서 세마포어를 가지려하면, 레벨 태스크가 이미 세마포어를 가지고 있기 때문에, 세마포어가 풀어질 때까지 대기 상태로 진입 • RTOS가 실행할 태스크를 찾아보면, 레벨 태스크가 준비 상태이고, 버튼 태스크가 대기 상태이기 때문에 레벨 태스크가 실행이 되고, 결국 레벨 태스크는 ReleaseSemaphore를 이용해서 세마포어를 풀어준다. • 세마포어가 해제되어 있기 때문에, RTOS는 버튼 태스크를 대기 상태에서 실행 상태로 상태를 전이 한다.

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

  26. 세마포어와 공유 데이터 • 다중 세마포어 • 다중 세마포어를 사용하는 장점은 무엇일까? • 태스크가 세마포어를 가질 때 마다, 잠재적으로 같은 세마포어를 사용하는 다른 태스크의 응답이 느려진다. • 하나의 세마포어만 사용하는 시스템에서, 가장 낮은 우선순위의 태스크가 온도들의 공유 배열에서 데이터를 변경하기 위해 세마포어를 가지고 있다면, 가장 높은 우선순위의 태스크는 온도에 대해서는 신경 쓰지 않고 에러의 개수를 변경 시키려고 해도, 그 세마포어를 기다려야만 한다. • 다른 종류의 세마포어는 다른 종류의 공유 자원에 대응할 수 있다. • 주의 사항 • RTOS는 어떤 Task가 어떤 Semaphore를 가지는지에 대해서는 관여하지 않는다.

  27. 세마포어와 공유 데이터 • 세마포어의 다른 용도 (공유자원 보호 외) • 한 태스크에서 다른 태스크로 또는 인터럽트 루틴에서 태스크로의 간단한 통신을 위한 수단 • 세마포어를 사용할 때 문제점들 • 세마포어를 가지는 것을 잊어 버린다. • 세마포어를 풀어 주는 것을 잊어 버린다. • 잘못된 세마포어를 가진다. • 너무 오랫동안 세마포어를 가지고 있는다.

  28. 세마포어와 공유데이터 –우선 순위 역전 1 • 세 개의 Task A, B, C가 존재 • 우선 순위는 A가 가장 높고, 그 다음 B, C 순서이다. • Task A와 C는 동일한 세마포어를 참조하고 있다. • 문제 • 현재 우선 순위가 가장 낮은 Task C가 실행되는 동안, Task B가 발생했다. • Task B는 C와 공유 세마포어가 없기 때문에 대기 상태에서 해제되고, 실행된다. • Task B가 실행되는 동안, 우선 순위가 가장 높은 Task A가 실행되고, Task A는 C가 가지고 있는 세마포어 때문에 더 이상 실행되지 못하고, 대기 상태로 들어간다. 이때 우선 순위가 낮은 Task C는 Task B에 의해서 Semaphore를 해제하지 못한다. • Task B는 계속해서 실행된다. –우선 순위 역전 발생 • 우선 순위 계승 : 위와 같은 문제 발생시 일시적으로 Task C를 A와 동일한 우선 순위로 일시적으로 변경해서 문제를 해결하는 방법

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

  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로 작업 전환

  31. 세마포어와 공유데이터 - 주의사항 • 세마포어를 사용하는 모든 경우는 버그가 발생하길 기다리는 것과 같다. • 따라서, 프로그래머는 반드시 사용해야만 할 때 세마포어를 사용하고, 피할 수 있으면 사용하지 말아야 한다.

  32. 세마포어와 공유 데이터 –변형된 세마포어들 • 변형된 세마포어들 • 카운팅 세마포어(Counting Semaphore) • 여러 번 제공될 수 있는 세마포어. 세마포어는 정수로 구성되고, 세마포어를 얻을 때 1씩 감소하고, 세마포어를 해제할 때 1씩 증가한다. 만일 세마포어가 0이되면 더 이상 세마포어를 얻을 수 없고 대기 상태로 들어간다. 세마포어의 원형이다. • 리소스 세마포어(Resource Semaphore) 또는 리소스(Resource) • 세마포어를 획득한 태스크만이 세마포어를 해제할 수 있다. 공유 문제 해결에는 적절하지만, 두 태스크 사이의 통신을 위해서는 사용할 수 없다. • 뮤택스 세마포어(Mutex Semaphore) 또는 뮤택스(Mutex) • 우선 순위 역전 문제를 자동적으로 해결할 수 있는 세마포어

  33. 6.3 세마포어와 공유 데이터 –공유 데이터 보호 • 공유 데이터를 보호하는 방법들 • 인터럽트를 금지시키는 것은 시스템의 모든 인터럽트 루틴과 다른 태스크들의 응답 시간에 영향을 끼치는 가장 극단적인 조치이다. • 데이터가 태스크 코드와 인터럽트 루틴 사이에서 공유 된다면, 인터럽트 금지가 유일한 방법이다. • 이 방법은 빠르다. • 세마포어를 이용하는 것은 같은 세마포어를 원하는 태스크에만 영향을 미치기 때문에, 데이터를 보호하는데 가장 정확한 방법이다. • 태스크 전환을 금지하는 방법은 어떤 면에서는 두 방법의 중간에 있다. 이 방법은 인터럽트 루틴에는 전혀 영향을 끼치지 않지만, 모든 다른 태스크의 응답은 정지 시킨다.

  34. 세마포어와 공유 데이터 –공유 데이터 보호 • 공유 데이터 보호 방법 • 인터럽트를 금지 시키는 방법 • 세마포어를 사용하는 방법 • 태스크 전환을 금지 시키는 방법

  35. 세마포어와 공유 데이터 –비교 (1) • 인터럽트 금지 • 모든 인터럽트와 다른 태스크 응답 시간에 영향을 미치는 극단적인 조치 (인터럽트 금지 시 스케줄러가 마이크로프로세서의 제어권을 가져올 수 없기 때문에 태스크 전환 역시 금지 됨) • 데이터가 ISR과 태스크 코드 사이에 공유될 경우 공유 데이터를 보호하기 위한 유일한 방법 • 대부분의 프로세서에서 인터럽트 금지나 해제는 하나의 명령어로 처리된다. • 세마포어를 이용하는 방법 • 세마포어는 원하는 태스크에만 영향을 미치기 때문에, 데이터를 보호하는데 가장 정확한 방법이다. • 어느 정도 마이크로 프로세서의 시간을 소비한다. • 인터럽트 루틴에는 적용할 수 없다.

  36. 세마포어와 공유 데이터 –비교 (2) • 태스크 전환을 금지하는 방법 • 앞의 두 방법의 중간 단계 • 인터럽트 루틴에는 전혀 영향을 끼치지 않지만, 모든 다른 태스크의 응답은 정지 시킨다.

  37. 6장 요약 • 일반적인 실시간 운영 체제 (RTOS)는 데스크 탑의 운영 체제 보다 더 작고 더 적은 수의 서비스를 제공한다. 그리고, 좀더 응용프로그램에 밀착되어 있다. • RTOS는 다양한 제품을 살 수 있고, 일반적으로 직접 작성하는 것보다 구입해서 사용하는 것이 합리적이다. • 태스크는 RTOS 환경에서 작성되는 소프트웨어의 기본 단위이다. • 각각의 태스크는 항상 세 가지의 상태를 가진다. 실행, 준비, 대기 이다. RTOS에서의 스케줄러는 준비 상태의 태스크 중 가장 높은 우선순위의 태스크를 실행시킨다. • 각각의 태스크는 독자적인 스택을 가지고 있다. 하지만, 시스템의 다른 데이터는 모든 태스크간에 공유 된다. 그러므로, 공유 데이터 문제는 다시 등장할 수 있다. • 하나 이상의 태스크로부터 호출 되어도 잘 작동하는 함수는 재진입 가능한 함수라고 불린다. • 세마포어는 공유 데이터 문제를 해결할 수 있다. 한번에 한 태스크만 세마포어를 가질 수 있기 때문에, 세마포어는 공유 데이터를 버그로부터 지켜 준다. 세마포어는 가지다 와 풀어주다 의 두 종류의 연관된 함수를 가진다. • 뮤택스, 이진 세마포어, 카운팅 세마포어는 RTOS가 제공하는 일반 적인 세마포어 들의 종류들 이다. • 공유 데이터를 보호하는 세 가지 방법은 인터럽트 금지, 세마포어 사용, 태스크 전환 금지 이다.

More Related