선점형 커널은 ISR 에서 복귀 한 후에 스케쥴러가 CPU 점유권을 최상위 우선순위를 갖는 테스크에게 넘겨준다고 했었습니다.

그!런!데!!!!!!

도대체 이놈의 스케쥴러가 어떻게 최상위 우선순위 Task 를 검출해 낼까요?

여러가지 알고리즘이 있을수 있지만, 제가 공부하는 uC/OS 에서 소개하는 알고리즘을 하나 소개해 드리지요 ㅋ

컴마스터인 신태민 교수님께서 OS 도입 초창기에 이 알고리즘을 보신 후에 감탄을 금치 못하셨다는 후문이 ㅋㅋ

우선순위가 255까지 있는 커널이 있다고 가정합니다.

낮은 숫자가 우선순위가 높다고 가정하고 가장 높은 우선순위를 찾아봅시다.

혹자는 이렇게 생각 할 수 도 있겠지요.

"야 그거 Ready 상태에 있는 Task 다 검색해서 정렬 쭈욱 한다음에 제일 높은 우선순위 찾으면 되는거 아냐?"

그렇게 해도 됩니다.

다만, 여기서 소개할려는 알고리즘이 굉장히 Simple 하고 멋있고 세련되고 빠른 방법이기에 소개하려는 것이지요 ㅋ

(1) 각 우선순위를 8열로 나누어 정렬한다
(2) OSRdyGrp 이라는 1byte 변수를 만들고, 이 변수의 각 비트는 각각의 행을 대표한다.
(3) 각 그룹의 8개의 Task 들 중에서 하나라도 Ready 상태가 되면 OSRdyGrp 의 해당 비트를 1 로 Set 한다.
     이 변수를 만들기위해 검색을 하는 과정에서 각 그룹별로도 각각의 우선순위에 해당하는 Task 가 Ready 상태이면 1, 아니면 0 으로 하여 OSRdyTble[] 이라는 배열의 맴버 변수들의 값을 채워 넣는다.


(4) 이렇게 해서 완성된 OSRdyGrp 라는 변수를 OSUnMapTlb[] 라는 LookUp Table 에 대입하여 값을 얻는다.


이 테이블은 0~255 의 숫자를 Binary 로 표시할때 제일 먼저 1이 나오는 bit 의 순서를 써 놓은 것이다.

(5) (4) 에서 나온 결과값을 OSRdyTlb[index] 의 index 값으로 사용하여 OSRdyTlb[index] 값을 얻어낸다.

(6) 다시 OSUnMabTlb[OSRdyTlb[index]] 로 다시 Look-Up Table 의 값을 얻어낸다.



(7) (4)에서 여러분이 얻어낸 값은 "몇번째 그룹에서 최고 우선순위를 갖는 Task 가 Ready 상태인가? " 이고
     (6)에서 여러분이 얻어낸 값은 "해당되는 그룹에서 몇번째 순서의 Task가 Ready 되어있는 상태중에 최고 우선순위인가?" 이다.


(8) 즉, Ready 상태에 있는 최고 우선순위를 최종적으로 알아내기 위해서는

( (4)번 결과 << 3 ) + (6)번 결과

이다. 여기서 좌로 3비트 쉬프트 시킨 이유를 그룹을 8개씩으로 끊어 놓았기 때문이다. (2의 3승)


이해가 되시나요??

한번 스윽 읽어보는것만으로는 잘 이해가 안되실 것입니다.
저도 직접 구현해보기 전에는 신기하기만 할 뿐이였으니까요 ㅋㅋ

포스팅전에 확실하게 이해하기 위해서 제가 방금 1시간을 투자해서 위의 알고리즘을 구현해보았습니다.


보이시나요? 잘 찾아내지요?

체크되어있는 것들이 Ready 상태입니다. ㅋ

하나도 체크가 안되어있으면 레디상태인 테스크가 없다라고 메시지가 뜹니다.

어떻게 아냐구요??

if (OSRdyGrp == 0) 겠지용?? ㅋㅋ

아래는 제가 C# 으로 간단하게 구현해 놓은 프로젝트 입니다.

참고하실분을 받아서 보시길 바랍니다.

Visual Studio 2010 SP1 으로 제작된 것이니, 프로젝트 안열리시는 분들은 그냥 .cs 파일에서 알고리즘만 간단하게 보시기 바랍니다.

따로 다중 클래스화 시키지 않았으니 무리없이 보실수 있을 것입니다.

그럼 바이바이

Posted by J.Bear

댓글을 달아 주세요

RTOS 가 갖을 수 있는 취약점이 또 하나 나오는군요.
이번 개념 굉장히 중요합니다.

일단 이 문장은 기억하세요~

"우선순위 전도"를 해결 할수 있는 해결책은 "우선순위 상속"이고,
"우선순위 상속"을 하기 위해서는 커널이 "동적 우선순위"를 구현 할 수 있어야 한다.


오케이??

자! 다시 각하와 국무총리, 필자와 화장실을 들고 와 봅시다.

각하와 필자가 갑자기 큰일이 마려워졌어요 ㅋ 화장실은 1칸밖에 없고 열쇠도 1개밖에 없습니다.
이 열쇠는 다른 이름으로 "세마포어" 라고 부르고, 이 열쇠관리는 화장실 관리인인 커널의 "스케쥴러" 가 합니다.

필자는 비록 우선순위가 가장 낮지만, 재빠르기때문에 각하와 국무총리님이 화장실을 가고 싶어하기 전에 관리자에게 "열쇠점 주세요" 해서 화장실에 가서 일을 보기 시작했습니당 ㅋㅋ

신나게 일을 보고 있는데 각하가 급하게 나타나서리 "나도 화장실이 급하다. 열쇠 점 줘" 이랬습니다 ㅋㅋ 그랬더니
관리자가 "열쇠 없는댑쇼?? 기둘리셔야 할듯 ㅋㅋ" 이러는 거에요 ㅋㅋ
아무리 각하라지만, 민주주의 사회에서 이미 일보고있는 저를 끌어낼수는 없는 노릇이지요 ㅋㅋㅋ
그래서 각하는 "흠.. 그럼 열쇠가 다시 나올때 까지 기다리도록 하지. 어쩔수 없으니까... " 이러면서 대기를 타기 시작합니다 ㅋㅋ

제가 빠르게 일을 보고 나온다면야 문제가 커지지는 않겠지요 ㅋㅋ 그래서 빠르게 일을 보려고 하고있는데 갑자기 국무총리님이 " 아 커널. 나 급하게 미팅이 잡혔어. 씨피유좀 부여해조 나 일좀 하게" 라는거에요 ㅋ

아나 얼척이 없어서 ㅋㅋ 커널은 국무총리님이 일을 보신다니까 씨피유 점유율을 저보다 우선순위가 높은 국무총리님에게 줘버리는거지요 ( 대통령이 우선순위가 가장 높지만, 화장실(공유자원) 이라는 자원을 요청하는데 쓰고 있어서 씨피유 점유율을 부득이 하게 못 주는것입니다. 국무 총리는 화장실을 요청한게 아니니까 씨피유 자원을 주는 것이지요)

국무총리님이 한창 일을 열심히 합니다. 쭈욱, 오랜기간 ㅋㅋㅋ 일을 다 마치고 커널에게 "나 일 다 끝났다" 이러니까 커널은 누구에게 이제 씨피유를 서비스 해줄까~~~ 하고 둘러봅니다. 각하와 제가 레디 상태인데 둘다 화장실을 요구하는데 키는 저한테 있었지요 ㅋㅋ 제가 반납을 한적이 없으니까 ㅋㅋ 그래서 저한테 씨피유을 부여해줘요 ㅋㅋ

저는 이제 신나게 일을 보고 난 후 " 다 썼어요 키 반납할께요 " 라고 말하죠 ㅋ 그제서야 관리자는 최고 우선순위였던 각하에게 " 각하 키가 왔습니다 이용하시지요~" 라면서 키를 주죠 ㅋ

자 여기서 생각해 볼까요??

각하는 1순위였는데 실질적인 우선순위는 어떻게 되어버렸습니까? 3순위였던 저보다도 낮아져 버렸죠??

이렇게 되는 현상을 "우선순위 전도 (Priority Inversion)" 이라고 부릅니다

공유자원의 한정성 때문에 어쩔 수 없이 최고 우선순위를 대기 태우는 일이 발생하더라고, 빨리 공유자원을 풀어서 최 우선순위 테스크에게 서비스를 해줘야 커널의 본질에 맞는데 이것은 뭐 2순위 3순위 애들까지 다 서비스 해주고나서야 맨 꼴지로 최 우선순위 테스크를 서비스 해주는 상황이 벌어져버리니 황당할 노릇이지요 ㅋ

위의 비유는 여러분의 이해를 돕기 위한것이고, Task 실행도를 살펴보지요~ 제가 햇던 이야기들이 고스란히 들어있습니다.


자 이해 되세여? ㅋㅋ 테스크 1이 꼴등으로 실행되어 버리네요 ㅋㅋㅋ

이런 문제를 해결하기위한 방법으로 어떤 것이 있을까요???

화장실을 이용하고 있던 저의 우선순위를 잠시동안 각하와 동급이나 그 이상으로 만들어 주는것입니다.

즉, 각하의 우선순위를 "상속" 해 주는것이지요 ㅋㅋ

그럼 , 제가 일보고 있을때 국무총리가 자기 일 있다고 CPU 서비스좀 해달라고 했을때 스케쥴러는 " 그럴수 없습니다 후달수 님아~~ " 이러면서 저는 꾸준히 화장실을 재빠르게 이용하겠죠 ㅋㅋ

다 이용한 후에 다시 제 우선순위를 원래의 양민 레벨로 돌려주고 나면 바로 최고 우선순위인 "각하" 께서 화장실을 이용하게 되시고~ 다 이용하신 후에 국무 총리 님이 업무를 보시게 되는것입니다 ㅋㅋ

이제 커널이 좀 제대로 돌아가는것 같지요?? ㅋ

요로코롬 돌아가게 됩니다 ㅋㅋㅋ

이제 맨처음에 꼭 기억하셔야 한다던 한문장이 이해가 되시지요?? ㅋㅋ

이렇게 공유자원을 이용할때 최고 우선순위를 일시적으로 부여 하는 행위를

우선순위 상속 (Priority Inheritance) 라고 부르고, 이 행동을 할 수 있으려면,

어플리케이션이 실행중일때 우선 순위를 바꿀 수 있는 동적 우선순위(Dynamic Priority) 를 커널이 구현할수 있어야 한답니다 ㅋㅋ

이해가 되셨기를 바랍니다

Posted by J.Bear

댓글을 달아 주세요

  1. 1 2014.06.12 22:26  댓글주소  수정/삭제  댓글쓰기

    제가이해하는게 맞는지 궁금하네여.

    우선순위 3순위가 cpu 작업을 먼저할수있는 권한을 받자마자 1순위가 와서 1은 기다린다.

    이제 3순위가 cpu를 사용하려는데 갑자기 2순위가와서 "나바쁘니 내가먼저쓰고 다음에 너가써!"

    라면서 2순위가 cpu를 사용하고 1순위를줌(이때 키를 넘겨준게 아니고 임시로 2가와서 사용)

    그리고 1순위가 작업을 다하고 2순위에게 넘겨줌

    하지만 우선순위라면 1->2->3인데 지금은 3 -> 2 -> 1로 되어버렸음.

    이러면 뭔가 말이 이상해지니까 2를잠시 1과 동급이나 그이상으로 승격시켜서

    3 -> 0.5(1보다 높거나 같은 원래의 2순위) -> 1 이렇게 바꿔줄수있음

    3 -> 2 -> 1 == 우선순위 전도

    3 -> 0.5 -> 1 == 우선순위 상속

    마,,맞겠죵?!

    쓰다보니 정리가되었다... 헤헤헤

  2. J.Bear 2014.07.01 09:44 신고  댓글주소  수정/삭제  댓글쓰기

    공유자원이 엮여있는 경우에 발생하는 우선순위 전도를 말씀드린건데 위의 글쓴이분은 약간 이해를 잘못하신듯 합니다.

    테스크가 공유자원을 할당받아 사용하는 경우에는 그 테스크의 우선순위를 공유자원을 사용하는 한시적인 기간동안 최고의 우선순위로 만들어 줌으로써 공유자원 사용으로 생길수 있는 데드락 현상을 해결할수 있다는 부분인데.....

    • 잠룡 2014.09.02 18:44  댓글주소  수정/삭제

      글중에 우선순위가 낮아졌다는 표현은 잘못되었습니다 실행순서가 자원의 점유와 대기로 인해 우선순위와 다르게 수행된 상황이 우선순위전도입니다

  3. ㅇㅇ 2014.12.13 18:04  댓글주소  수정/삭제  댓글쓰기

    여러 글들 찾아봐도 이 개념이 이해가안됫었는데 이 비유보고 이해가 확되네요 감사합니다 !!!


우선순위를 논해야 될때가 되었군요 ㅋㅋ

전 강의에서 비선점형 커널과 선점형 커널 이야기를 하면서 우선순위 우선순위 했는데 감이 오셨어요?
사실 뭐 별게 없습니다~

어떤 Task 가 더 중요한 Task 인가??? 인것이죠 ㅋㅋ

곰곰히 생각해보면 이놈의 커널은 참 민주사회의 부패를 그대로 뺴다 박아 놓은놈 인것 같습니다.

온국민은 평등해야 하는데 실상 우리 사는 사회가 그렇지가 않잖아요 ㅋㅋ

아니라구요????

화장실이 한칸있습니다.
화장실 주인이 화장실에 들어갈 사람을 결정 할 수가 있어요 ㅋ

근데 저랑 각하랑 같이 응가가 마려운거에요 ㅋㅋ 그래서 화장실 주인한테 동시에 저 응가가..... 마려... 워...요...

라고 말했습니다. ㅋㅋ 근데 이놈의 화장실 주인이라는 놈이 뒤 돌아 볼것도 없이 무조건 "각하" 에게 화장실을 쓰라고 한다는 것이지요 ㅋ
(아... 더러운 세상 ㅋㅋ 이러실 필요는 없어요 ㅋㅋ 각하보다 쫌만 더 빨리 요청하면 내가 쓸수 있으니까요 ㅋㅋ)

다음강의에서 계속될 Priority Inversion 과 세마포어를 이야기하면 지금과는 조금 상황을 이야기 할 수 있습니다 ㅋ

(흠.. 쓸것도 없는데 왜 이 글을 쓴다고 했을꼬 ㅋㅋㅋ)

Group Priority 라는 것이 있습니다 ㅋㅋㅋ

그룹단위로 일단 우선순위를 한번 나눠 놓은 후에 세부 우선순위를 나누려는 개념이지요 ㅋㅋㅋ

Group 1 : 공자 맹자 예수 장자 + 필자
Group 2 : 찌우, 다람쥐, 토끼, 멍멍이
Group 3 : 지렁이, 무뇌충

역시 그룹 1이 킹왕짱입니다 ㅋㅋ

이제 스케쥴러는 그룹의 우선순위를 먼저 따진 후에, 각 그룹 안의 맴버들 각각의 우선순위를 다시 따져 줍니다 ㅋ

즉 Group 2 에서 찌우가 킹왕짱이더라고 Group 1의 핫빠리인 장자 보다 못하다는 소리이지요 ㅋㅋㅋ

사실 커널에 따라서 Group Priority 를 지원하지 않는 것도 있습니다 ㅋ

하지만 제가 사용하는 커널은 RTX Kernel 은 이를 지원하는군요 ㅋㅋ

Priority 의 숫자가 큰것이 우선순위가 높은 것일 수도 있고, 작은것이 높은것일수도 있습니다 ㅋ

즉, 커널 디팬던트 하다는 소리이지요 ㅋㅋ

메뉴얼을 꼭 살펴 보셔야 한다는 소리입니다 ㅋ

우선순위의 종류에는

(1) Static Priorities (정적 우선순위)
(2) Dynamic Priorities (동적 우선순위)

이렇게 크게 두가지로 나눈수 있는데요 ㅋ 머 딱히 설명 드리지 않아도 이제 감이 오지 않습니까? ㅋㅋㅋ

테스크의 우선 순위를 바꿀수 없다면 정적 우선순위요, 어플리케이션이 실행되는 동안에 태스크의 우선순위를 바꿀 수 있다면 이럿은 Dynamic 한 우선순위가 되는것이지요 ㅋㅋ

쉬운 개념이니 쉬어가는 코너로 생각하시고 넘어가시길 바랍니다 ㅋ

다음에 설명할

Priority Inversion 과 Priority Inheritance 가 중요한 개념이니까요 ㅋㅋㅋ  (우선순위 전도와 우선순위 상속) ㅋ

여려분에게 우선순위는 어떻게 되시나요??? ㅋㅋㅋ

아래는 제가 가지고 싶어하는 CPU 3960X ㅋㅋㅋ

Posted by J.Bear

댓글을 달아 주세요

중요한 개념입니다.

크리티컬 섹션으로 인해서 프로그램이 이상하게 동작 할 수 있지용 ㅋ

모르는 사람은 왜 이러나 하고 디버깅하기가 쉽지 않은데~ 한번 겪어본 사람은 그래도 접근을 할수는 있으니
이런게 있구나 하고 들어두시면 되겠습니다.

조금더 이해를 돕기 위해서는 Reentrancy(재진입성) 에 대해서 이야기하겠습니다.

: 함수는 함수인데, 언제 어느 시점에서든이 콜 되어도 문제가 없는 함수를 재진입성 함수라고 불러요.
좀더 직관적으로 설명을 드리자면, 1번 테스크에서 A 라는 함수를 콜해서 잘 돌고 있는데 갑자기 인터럽트가 걸려서
A 라는 함수를 또 콜해버리고, 인터럽트에서 복귀하니까 다른 우선순위 높은 테스크로 CPU 점유율이 넘어갔는데
그녀석이 또 A라는 함수를 불르고......

이런식으로 진행이 되어도 아무런 문제가 없는 형태의 함수를 재 진입성 함수라고 합니다 ㅋ
대부분 Local 변수들로 짜져있겠죠??

그래가 각 테스크의 스텍에 변수들을 생성하니까, 여기서 불르던 저기서 불르던 서로 별개의 변수가 될것 아닙니까 ㅋㅋ

그런데... 함수에서 전역 변수를 사용한다면????
아 이거 이야기가 달리지지요 ㅋㅋㅋ

예제 나갑니다.

int Temp; (어거 전역입니당~~)

void swap(int *x, int*y)
{
   Temp = *x;
      <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<   인터럽트!!!!!
   *x = *y;
   *y = Temp;
}

자 위와같은 함수를 하나 짜놓았다고 가정합시다.

x 와 y 에 들어있는 값이 2와 3이라고 가정하구요~

메인에서 2와 3의 위치를 바꺼조 하면서 swap 이란 함수를 콜했어용~

Temp 에다가 2를 집어넣고 x 에 y 를 집어넣으려던 찰나에 인터럽트가 걸린 겁니다.

그래놓고 나서 우선순위가 높은 다른 테스크로 CPU 점유권이 넘어가버렸다고 가정하지요

그 테스트에서는 4와 5라는 값을 바꾸려고 swap 을 콜했군요.

일단 4,5라는 값은 잘 바뀔것입니다~ 하지만 이때 Temp 에 있던 2라는 값이 4로 Overwrite 되어 버리지요~

그다음 원래 테스크로 CPU 가 돌아왔을때 x=3, 이지만 y=4 라는 이상한 결과가 나와버리는 것이지요~

Temp 는 전역변수였으니까요 ㅋㅋ 

이런 함수들은 비재진입 함수라고 부릅니다 ㅋ

이렇듯 비 재진입 함수들에서 절대로 분리가 되면 안되는 코드의 구역이 존재합니다.
만약 분리가 되어버려 왔다리 갔다리 하다가 여러 곳에서 진입을 할경우 데이터가 손실될 우려가 있는 구간.

이런 구간을 우리는 Critical Section  이라고 부릅니다.

이런 구간을 막아주기 위해서 우리는 Critical Section 앞쪽에서 인터럽트 Disable , Critical Section 이 끝난 후에

인터럽트 Enable 을 해주는 방식으로 보호합니다~ 

일단 한번 진입하고 나면 무조건 쭈욱 돌아라 라는 의도이지용 ㅋ 

대표적인 Critical Section 을 하나 알려드리지용~

USART TX 통신 구현시에 Ring Buffer 를 구현하지용 ㅋ

void USART_Transmit( u8 data ){
u32 tmphead;
// Calculate buffer index //
__disable_irq();
tmphead = (u32)( USART_TxHead + 1 ) & (u32)USART_TX_BUFFER_MASK;  
__enable_irq(); 

if(tmphead == USART_TxTail)
BufferOverFlow =1;
while ( tmphead == USART_TxTail );
USART_TxBuf[tmphead] = data;                 // Store data in buffer
__disable_irq();
USART_TxHead = tmphead;                      // Store new index
__enable_irq();
USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); // Enable TX Interrupt    


실제로 제가 사용하는 코드의 일부입니다.

붉은색으로 표시 해 놓은것이 보이시지요??

저곳이 바로 크리티칼 섹션입니당~~~

왜냐구요???

아 그것은.... 일단 이해하실수 있는분만 이해하시거나 아래 댓글로 질문해주세요 ㅋㅋ
주제에 벗어나는것 같으니까 나중에 설명할 기회가 있으면 USART 통신 설명하면서
한번 다루도록 하겟스무니다이~~~ ㅋㅋ 

흐음.. 사진이 없으니까 허전하넹 ㅋㅋ 

최근에 아주 재미있게 본 파파씨네 펭귄들 사진이라도 올려야겠따 ㅋㅋㅋ



 
Posted by J.Bear

댓글을 달아 주세요

이제 슬슬 RTOS 의 핵심으로 들어가고 있습니다.

시작하기 전에 사진 한 컷! 이것은 현재 저의 입천장 사진입니다.

사실 요전 4일동은 39도가 넘는 고열에 시달리며 새해를 맞이했지용.

응급실에서 주사를 맞으면서 ㅋㅋ

태어나서 이렇게 짧은기간에 이렇게 많은 병원과 주사를 맞아본 기억이 없습니다.

그때 고열로 시달리다가 입천장이 다 헐어 버려서 지금 음식도 못먹고 허미.....

 

보이시나요. 헐어서 살이 다 벗겨지고 노랗게 염증도 생기고 ... ㅠㅠ
정말 이렇게 공부해서 어디다 쓰나, 무슨 부귀영화를 누리자고 이러나 싶기도 하지만 ㅋㅋ
일단 스케쥴러와 커널의 종류에 대해서는 공부해놓고 마저 생각합시다.

그럼 시! 작!

1. 스케쥴러

이름부터가 딱 직관적입니다. 스케쥴을 짜주는 놈이지요. 디스패처(Dispatcher) 라고도 하는데요, 이놈이
다음번에 실행할 테스크를 결정한답니다.
Context Switching 이 일어나기 위한 조건은 Interrupt Service Routine 이에요 ㅋ

왜 그러냐규요??

ISR 에 의해서 테스크는 자신의 CPU 점유권을 놓게 되지요~ 그것이 Tick ISR 이던, Timer ISR 이던 DMA ISR 이던 상관없이 말이에요~

그 이후에 CPU 점유율은 커널의 스케쥴러가 갖습니다.
어떤 형태의 커널인지에 따라 이 스케쥴러는 레디 상태에 있는 테스크 들로부터 다음에 서비스를 해줘야 할 테스크를 결정하게 됩니다. 대부분의 커널들은 우선순위가 높은 테스크에게 점유율을 넘기지용~ ㅋㅋ

스케쥴러~ 내 프로그램의 스마트한 교통 순경 정도로 생각해 두시면 좋을듯~~

2. 커널의 종류 : 비선점형 커널, 선점형 커널 로 나눌 수 있다.

(1) Non-preemptive Kernel (비 선점형 커널) 

 선점을 하지 않는 커널. 먼저 점령을 하지 않는 커널.

풀어쓰니 위와 같이 되는군요?? ㅋㅋ 먼저 점령을 하지 않는다. 뭐를? CPU 점유권을~

쉬운 개념인데 이름을 좀 아리까리 하게 지은것 같기도 해요 ㅋㅋㅋ

이전 포스트에서 커널의 종류를 나누는 기준은 ISR 후에 어떤 Task 로 CPU 점유권을 넘길것이냐에 대한
원칙이 무엇이냐에 따라 종류가 결정된다고 했었던 것 기억나시나요?

비 선점형 커널은, 무조건 ISR 로 뛰어들어가기전에 돌고 있던 Task 로 다시 CPU 점유권을 넘기는 커널입니다.
아무리 우선순위가 명박이 할애비 보다 높다고 해도 필요없어요 ㅋ 꿋꿋하게 원래 돌던 놈에게 다시 넘겨주조 ~ ㅋ

그럼 이 커널은 멀티태스킹을 언제하느냐???
태스크에서 자체적으로 자신의 CPU 점유권을 놓아야 합니다 ~ OS_Dly_wait(10) 같은 방식으로요 ~ ㅋㅋㅋ

 


그림으로 보니 한결 더 이해가 빠르지요?? ㅋㅋ

그럼 어떤 특징이 있을까용?

1. 인터럽트 지연시간이 짧습니다. (흠.. 개인적으로 저는 인터럽스 지연시간은 잘 모르겠고, 인터럽스 응답시간과 복귀시간이 짧다고 말하고 싶은데 빌딩블록에는 이렇게 써있네요 ... ㅠㅜ)
2. 테스크 레벨에서도 비재진입 함수를 사용할수 있습니다 (테스크 자신이 제어권을 넘겨주기 전에는 절대로 다른 테스크로 제어권이 넘어가지 않기 떄문에, 일 다하고 제어권을 넘기면 됨ㅋㅋ)
3. 테스크의 응답성이 떨어진다. (재수업게 졸라 수행시간이 긴 테스크가 돌고있다고 가정해보세요 ㅋㅋ 우선순위가 졸라 높은 테스크가 대기중인데 제어권이 넘어올 생각을 안한다면?? 후덜덜 ㅋㅋㅋ) 

초창기 리룩스 커널과 Window3.1 이 비선점형 커널이였습니다 ㅋ
그래서 한번 뻑나면 컴퓨터 전원을 끄는 것 밖에 방법이 없었지요 ~ ㅋㅋ

도대체 CPU 점유율을 뻇어올 방법이 없거등요 ㅋㅋㅋ 훗날 다 선점형 커널로 바뀌었지만 말이죠 ㅋ

하지만 반대로 프로그램을 정말 잘 짜놓았다면?? 굉장히 안정적으로 돌릴수 있는 커널은 비 선점형이 되겠지요 ㅋㅋ 

(2) Preemptive Kernel

선점형 커널 ㅋㅋ 

이제 감이 오시죠? ㅋㅋ

딱 반대입니다. ISR 로 부터 복귀할 때 스케쥴러는 최 우선순위를 갖는 테스크에게 씨피유 점유율을 넘깁니다 ㅋ

좀더 복잡한 로직으로 동작하지만 프로그램의 응답성이 굉장히 개선이 되겠지요?

최고 중요한놈부터 꾸준히 서비스를 할수 있어 지니까요 ㅋㅋ

선점형 커널에서는 최상위 우선순위 태스크가 언제 CPU 의 서비스를 받을수 있을지 알수 있습니다.

하지만, 그렇다 보니까 Critical Section , 비재진입 함수의 사용 등에서 문제점이 발생하지요 ㅋ

아직 일이 덜 끝난상태에서 나보다 중요한 놈에게 CPU 서비스가 넘어갔는데 같은 비재진입 함수를 콜해버리고이러면 데이터가 완전히 꼬여버리자나요 ㅋㅋ

그래서 상호 배제적으로 공유자원에 접근을 하기 위한 노력들이 일어납니다 ㅋ

총 4가지의 방법이 있는데요~ 그것은 다음에 다루도록 하구요 ㅋ 지금은 제목만 알려드릴게요

1. 인터럽트 Enable/Disable
2. Semaphore 의 사용
3. TAS (Test and Set)
4. Scheduler Lock/Unlock

의 방법을 이용해서 공유자원에 상호 배제적으로 접근할 수 있답니다 ㅋㅋ

아 이번 강의 너무 길어지네.

너도 다시 공부하고 정리하는거라서 시험공부도 되고 좋네요 ㅋ
이거 그대로 인쇄해서 읽어보면서 셤공부해야겠네 ㅋ
하다가 빼먹은거 있으면 나중에 보충설명 해 드릴게요 

일단 선점형 커널의 이벤트 그림 올려드립니당

 

Posted by J.Bear

댓글을 달아 주세요

  1. J.Bear 2012.01.03 21:44 신고  댓글주소  수정/삭제  댓글쓰기

    아~ ㅋ 한가지 더 이야기했어야 하는데 ㅋ

    그래서 요즘 나오는 윈도우들 보면 예전처럼 응답없다고 컴터 전원을 꺼야될 정도로 먹통이 되지 않자나요? ㅋㅋ

    선점형 커널이라서 그렇습니다 ㅋ

    컨트롤+알트+델 눌러서 빠져나간다음에 문제가 되는 테스크를 죽여버릴수도 있지요? ㅋㅋ

    예전에 윈도우 3.1 때는 안됬었답니다 ㅋㅋㅋ

    이 두 가지 비교해 보시면 두 커널의 차이점이 극명하게 드러나는군요 ㅋ

RTOS 의 핵심 기술!!!!! 

Context Switching 납시셨습니다 ㅋㅋㅋ

하나의 CPU 로 다중 작업을 수행할수 있도록 해주는 아주 혁신적인 기능이지용 ㅋㅋㅋ 

일단 이놈의 Context Switching 을 이해시키기 위해 아주 간단하게 그림을 하나 그려보았습니다

 

각기 다른 일을 할 수 있는 뇌가 여러개 있다고 생각해 봅시다.

이 모든 일은 동시에 수행이 되어야 하며, 일을 수행할 몸은 한개 밖에 없다고 가정해 보지요

프로그래머는 각각의 뇌에 모두 같은 몸이 달려있다고 가정한 후 프로그래밍을 마쳤습니다.

이제 해야할 일은???

징그럽긴 하지만, 가운데에 머리에사진에 내 뇌를 가져다 끼우기만 하면 되네요.

1번일이 하고싶을때는 1번 뇌를, 2번일이 하고싶을 떄는 2번 뇌를, 3번일이 하고싶을때는?? 3번뇌를 ㅋㅋㅋ 

이렇게 뇌를 통채로 재빠르게 바꾸어주는 과정을 Context Switching 이라고 부릅니다

우리나라 말로 '문맥 전환'

각 테크스가 저 주변의 뇌에 해당되는 것이구요, 실제로 장작되는 뇌를 골라서 끼워넣어주는 작업은

커널의 스케쥴러라는 놈이 수행하게 됩니다.

저 뇌들중에 어떤 뇌를 끼워 넣어 줄 것인가에 대한 기본 원칙이 무엇이냐에 따라 커널의 종류가 선점형과 비 선점형 2가지로 나뉘게 됩니다. 이는 뒤에서 한번더 다뤄보도록 하죠 중요한거니까 ㅋ

그럼 좋은 커널이란 Context Switching 이 빠른 커널이다!!! 라고 정의할수 있나요??

꼭 그렇지많은 않습니당 ㅋ CPU 가 가지고있는 레지스터의 양에 따라서 부과되는 오버헤드의 양이 달라지기 때문이지요. 즉, Context Switching 이 커널 디펜던트 하기도 하지만 CPU 디펜던트 하기도 하므로, 이것 만으로 커널의 성능을 결정 짓기에는 무리가 있다라는 소리입니다.

각각의 테스크 들은 선언이 되어 컴파일 되는 순간 스텍에 자신의 공간을 갖습니다.

CPU 는 Context Switching 을 시작할때 현제 자신의 레지스터 정보를 Stack 에 푸쉬푸쉬푸쉬푸쉬 해서 쭈우 집어 넣어놓고, 수행할 테스크의 레지스터 정보를 팝팝팝팝팝팝 해서 채워놓고 아무일도 없었던것 처럼 해당 일을 수행합니다.

그러다가 또 C.S 를 해야할 떄가 오면 다시 현재의 레지스터 정보를 스텍에 저장, 필요한 정포 팝 해서 수행

이런 일을 굉장히 빠르고도 효율적으로 수행하면서 멀티 테스킹을 하게 되는 것이지요~

 
Posted by J.Bear

댓글을 달아 주세요

  1. 나다 2013.03.15 18:34  댓글주소  수정/삭제  댓글쓰기

    지하철에서 님이랑 비슷한 생각을 해서 검색했더니 역시 똑같은 생각을 한 사람이 있군요

흠... 
앞 강의에서 Kernel 을 이야기 한김에 선점혐/비선점형 커널을 이야기 하고 싶은데
그러기에는, 아직 테스크와 스케줄러, 문맥전환에 대해 먼서 설명이 필요하므로 잠시 참고 다시 기초부터~ ㅋㅋ

테스크~ 어디서 많이 들어보지 않으셨습니까? ㅋ 

 
ㅋㅋ 아 욱겨 ㅋㅋㅋ

(특히 힘든, 하기싫은 ) 일 ㅋㅋㅋ

그렇죠 ㅋㅋ  사실 코드짜는게 그렇게 적게 힘들고 하고싶은 일은 아니죠 ㅋㅋ
아 네이버 정의 정확하네 ㅋㅋㅋ

여튼 말그대로 테스크는 일의 단위 입니다. 최소한 여기서 우리는 그렇게 생각하도록 하죠~

하나의 테스크는 크게 볼때 하나의 일을 하고 있는것입니다~

약간 다른 시각에서 보면 하나의 테스크에는 각기 다른 하나의 배경 시스템을 가지고 있습니다.
즉 무한루프를 가지고 있다는 소리지요~

### 여기서 잠시 ####

쓰레드(thread) 와 테스크(Task) 는 같은 말인가요? : 의견이 분분 한데요 약간 다르다는 사람도 있고 ㅋㅋㅋ
제 개인적인 생각으로는, 우리가 지금 공부하고 있는 분야에서는 같은 단어로 간주하고 이야기해도 크게 무리가 없다
입니다. ㅋㅋㅋㅋ 참고하세요~ ㅋㅋ

##################################

그럼 멀티 테스킹은 머냐???

멀티면 여러개라는 뜻 아닙니까 ㅋㅋ 스타 멀티플레이 할때 그 멀티 ㅋㅋ

즉, 태스크가 여러개다 -> (특히 힘들고 하기 싫은) 일이 여러개다 -> 아 ㅆㅃ

가 되는것이죠 ㅋㅋㅋㅋ  일도 많은데 이것을 내보고 다 하라고???

아 이럴바에는 그냥 테스크가 하나밖에 없던 슈퍼루프 방식이 좋았어 ㅆㅃ 이런생각이 들때쯤~~~~
엄청 뛰어나신 고수분들이 말을 해줍니다 ㅋㅋ

야~ 너는 어차피 슈퍼루프 방식 코드짜듯이 그냥 짜기만 하면돼~ 
각각이 하나의 일만 한다고 생각해놓고 쭈욱 코드를 짜 놓으면, 나중에 커널이란 놈이 알아서 번갈아가며 일을
효율적으로 시켜줄꺼야

라고 조언합니다 ㅋㅋㅋㅋ

이렇게 되고나면?? 멀티 테스킹을 하는것이지요 ㅋㅋㅋ

살짝 이해가 되시나요???


생각해보면 매우 당연한 이야기 입니다.

CPU 가 한개인데 무한루프를 여러개 돈다??? 무슨수로??? 말이 안돼자나요 ㅋㅋㅋ
CPU 는 한개인데 10가지 일을 동시에 한다??? 무슨수로??? 말이 안돼자나요 ㅋㅋㅋ

멀티 테스킹이란~~~ 

여러개의 CPU 가 있는것처럼 프로그램을 짜놓고 나면, 1개의 CPU 를 가지고 엄청 빠른 시간동안에
각각의 일들을 번갈아 가면서 처리하다 보니, 사용자의 입장에서 볼때는 동시에 여러가지 일을 처리하는것
처럼 느껴지게 되는 일련의 일처리 방식입니다. 

그럼 이런것들은 어떻게 이루어지나염???

그거슬 더욱 자세히 아실려면 다음강의를 보세요 ㅋㅋ
커널의 스케줄러와 문맥전환(Context Switching) 을 이해하셔야 된답니다 ㅋ

그럼 바이바이~~
Posted by J.Bear

댓글을 달아 주세요

익숙한 단어이지요??

리눅스 무슨 커널, 유닉스 커널 등등 들어보기는 많이 들어보시지 않았나요?

이게 앞에서 말한 Foreground/Background System 의 개량형입니다.

Kernel 이란 Multitasking System 의 일부분 입니다. 
각각의 테스크들의 Management 와 각 테스크간의 통신을 수행해주는 녀석이죠~

제가 포스팅하는 M3 에는 RTX-Kernel 이 올라가 있지요? ㅋㅋ
다른 커널들도 많답니다. 

간혹 이렇게 커널 기반에서 펌웨어를 개발하시는 분들 중에서 "OS 를 올렸다, 얹었다" 
이렇게 표현하시는 분들도 있습니다.

물론 틀린 표현은 아니지만, 저는 ㅋㅋㅋ 좀 낯이 뜨거워서 잘 사용하지 않습니다 ㅋㅋ
사실 별로 대단한것이 아니니까요 ㅋ

훗날 WinCE 나 리눅스 같은 OS 정도 얹어놓고 A8 코딩쯤 할때나 저렇게 표현해야할듯 ㅋㅋ


커널기반 프로그래밍을 이해하실려면, 아셔야 할것이 좀 있습니다.

스케쥴러, 우선순위, 세마포어, 뮤텍스 등등... 이것들은 차차 설명하고 지금은
커널기반의 프로그램이 전경/배경 시스템과 어떻게 다른지만 살펴보지요

1. 커널을 사용하면 2.5% 정도의 시간을 더 허비한다.
2. 커널 사용시 ROM, RAM 을 더 많이 사용하게 된다.

-> 머야 이건 좋은게 아니자나요?? ㅋㅋ 하지만!!!!!

1,2번을 포기함으로 인해서 돌아오는 이점은 엄청 나다는 사실을 명심하세요~

3. Real-time Kernel 은 MCU 의 수행 시간을 컨트롤 한다. (젤로 급한 놈부터 서비스 해준당)
4. 한 프로그램에 여러개의 task 가 존재한다. (즉, 무한루프가 여러개 존재한다.)
5. 이 각각의 task 들은 자기 자신이 온전히 CPU 를 독점하여 사용하는 것처럼 동작한다.

흠... 너무 뜬구름 잡는 식인감 ㅋㅋ

더욱 자세히 아실려면 이 뒤의 개념을 좀더 이해 하셔야하니까요 간단하게 읽고 넘어가세요

아래와 같은 비교가 도움이 되려나 모르겠네요~

(1) 전경/배경 시스템 : 부대의 배치, 일하는 종류, 일을 시작하고 끝내는 시간, 일을 수행하는 순서 등을 모두 하나하나 내가 직접 계산하고 결정해서 한치의 어긋남이 없이 돌아가도록 만들어 놓겠다!!! 

(즉!!! 일을 시키는 사람이 천재이거나 완벽주의자거나 ㅋㅋ 둘중하나)

(2) Kernel 시스템 : 흠...내밑에 강한 권력을 갖는 꼬봉을 하나 만들겠다.(Kernel). 나는 내가 해야할 일들을 크게 가닥을 쳐서 뭐가 더 중요한지 순서만 매겨놓고 일을 수행하는것은 꼬봉에게 맡기겠다. 내 꼬봉은 나의 의도를 참 잘 알아서 중요한 일부터 잘 번갈아가며 일을 착착 진행해 나갈것이다.


(오 스마트 가이의 일처리 방식 ! ㅋㅋㅋㅋ)

점점 뒤로 가시다 보면 진짜 이놈 스마트 하구나 라고 느끼게 됩니다 ㅋ

그럼 아래의 간단한 그림 한편 보시면서 생각해 보시길 바라며 바이바이~
 

 
Posted by J.Bear
TAG Kernel, RTOS

댓글을 달아 주세요

아....

키보드를 들어버렸다 ㅋㅋㅋ 꽤나 긴 포스팅이 될 것 같은뎅 ㅠㅠ

사실 예전부터 정리한다 정리한다 하다가 못한 부분인데

졸업고사도 있고 하니, 다시 공부하는 김에 이곳에서 정리하여 둔다.

많은 이들이 Real-Time Operating System 을 이해하는데 조금이나바 도움이 되었으면 한다.

1. Foreground/Background System 

흔히들 Superloop 방식으로 많이 알고 있다. 왜??? while(1) 때문에 ㅋㅋㅋ
프로그램을 저 무한루프 안에 다가 다 때려 박아 주니까 ㅋㅋ 저 루프를 슈퍼루프 라고 부른다 ㅋㅋ
Atmega 계열, PIC 계열 등의 저급 MCU 코딩에 주로 사용하였을 것이다.

소형이면서 복잡하지 않은 시스템에 적합하다.

그렇다면 도대체 이놈의 슈퍼 루프가 전경(Foreground) 이냐 배경(Background) 이냐? ㅋㅋ

이것을 잘 알아두면 이야기가 쉽다. 또 프로그램을 어떻게 짜야할지도 감이 온다. 

답은!!! 백그라운드 이다. 즉 무한루프 안에서 여러가지 함수들이 쭈우우우욱 콜 콜 콜 되고 있어야한다는 소리.

그럼 전경은 뭐임????

정답은 !!!! ISR 입니다. Interrupt Service Routine !

Background 에서 열심히 작업을 하는데, 꼭 필요한 시기에 작업을 이행 해 주어야 할 것 만 같을때!!
이때 치고들어오는 것이지요. (배경, 너는 좀 쉬고있어. 내가 급하니까 재빠르게 좀 처리할께 의 느낌)

 말로만 들으니 감이 안오는가???

그림 나갑니다 ~ ㅋㅋ

 
백그라운드가 쭉쭉 일하는데 인터럽트가 걸리면 무조건 멈추고 인터럽트부터 처리를 해주고 다시 백그라운드로 복귀하고 있지용 ㅋㅋㅋ

코드를 어떻게 짜야할지 감이 오시나요??

예전에 우리 연구실에 있던 대장 노스페이스 아이가 아트메가 코드를 짜고있길래 뒤에서 보고 있었지요.
메인문에 슈퍼루프가 떡 하니 있는데 그 안에서 하는 일이 하나도 없더이다. ㅋㅋㅋㅋㅋ
그래서 물어보았죠. 왜 너는 메인문에 코드가 하나도 없냐? ㅋ
대장 왈 : 모든것은 인터럽트에서 처리해야하니까요 

알려주려해도 말을 듣지않아서 걍 말아버렸습니다만, 여러분들은 이런 생각을 하시면 안됩니다.

배경이란말이 왜 붙어있을까요? 저 슈퍼루프에서 시퀀셜하게 프로그램은 계속 돌아가고 있어야합니다.
인터럽트는 최소한의 시간에만 머물수있도록 해주어야 이 시퀀스들이 깨지질 않죠. 훗날 코드를 보며 이야기 할 기회가 있으면 그 때 자세히 알려드릴게요.

일단 전경/배경 시스템의 장점

1. 프로그램의 구조가 직관적이며 이해하기가 상대적으로 쉽다.
2. 간단한 프로그램에 짜기에 용의하다.
3. 커널에 의한 메모리손실이나 수행시간적 손실이 없다.

단점

1. 프로그램이 복잡해 질수록 코드를 짜기가 어렵다.
2. 모든 함수는 우선 순위가 같기때문에 프로그래머 자신이 순서대로 잘 돌수있게 코드를 잘 짜주어야 한다.
(즉, 손이 많이 간다는 소리지요잉~ ㅋㅋㅋ)
 

다음번에는 전경/배경/ 시스템에 반대되는 개념인 Kernel System 에 대해서 작성하겠습니다.
실질적으로는 여기서 부터가 정말 RTOS 기초의 시작이겠군요 ㅋㅋ
그럼 다음시간에 ~ 

 
Posted by J.Bear

댓글을 달아 주세요

  1. 손님~ 2012.01.10 20:00  댓글주소  수정/삭제  댓글쓰기

    OS 좀 볼일이있어서 우연히 들어와 보게되었는데
    정말 도움이 많이 되었습니다. 감사합니다 ~~새해 복많이 받으세요~

  2. MISS!권 2012.01.25 21:41  댓글주소  수정/삭제  댓글쓰기

    대장 노스페이스 아이가..ㅋㅋㅋ 쩌는데..ㅋㅋㅋ

100% 맞는말이다 

 
Posted by J.Bear

댓글을 달아 주세요

  1. 권이석 2011.11.30 09:41  댓글주소  수정/삭제  댓글쓰기

    뭔 말이진 모르지만.. 결국 무한 루프 구만! ㅠㅠ;