임베디드/임베디드 레시피

TCB - Task , CS

twoweeks-within 2024. 12. 17. 02:54

Kernel Level의 Context Switching

 

 현재의 Context잘 보전 > 다른 곳에 갔다 와서 하던 일 계속 진행 가능! 

      ARM의 Context > 그림1 >  이 녀석만 잘 저장해두면됨

  > 해당 Task의 Stack에 저장

ARM의 Context

 

 Context Switching 할때 , 현재의 Context를 저장해 두는 방법

   >  Kernel이 어떻게 Task를 관리할까?

 

System상의 Task : 자기 자신만의 Stack과 TCB (Task Control Block)가짐

       TCB :  각 Task를 Control하기 위해 > Task의 정보를 저장해 놓는 Data Structure

               > Scheduling과 Context Switching을 위한 정보들이 들어감

               Ex)  Task name, Task Stack Pointer, 기다리는 wait Signal, priority

 

각각의 TCB : 각 Task의 Priority, SP (Stack Pointer) 가리킴

 

현재 Wait, Ready Task의 TCB의 Stack :   

            방금 전까지 실행하던 Context를 마지막에 Stack에 넣음 > 그 Stack의 끝을 가리킴

(stack 은 높> 낮) :( Full Descending Stack)

 >  각각의 Task : 자기가 어디까지 실행되었었는지를 항상 간직

   ( Stack 입장 ) 아까까지 쓰고 있던 SP를 그대로 복구

 

IF)  Task2 : wait > Ready : SP가 가리키고 있던 Context를 그대로 다시 CPU의 Register에 복사 > Context Switching 완성

 >  SP :  Context복구 > pop 한 만큼 변화한 그 자리부터 다시 해당 Task의 Stack으로 사용

    >  실행되던 Task : Stop 

   <> 다른 task 실행이 변경 : 반대로 해당 Task의 Stack에 Context를 저장(Push)

                        > SP를 Push한 만큼 update >  CPU사용권에서 벗어나면됨

TCB의 Status

    :  Scheduler에게 현재 Task의 상태를 알려주는 flag

        >  Ready 상태인지 아닌지를 알려주는 역할

   Ready 상태, Wait 상태의 구분

     Wait :  Task가 wait_signal()을 이용해서 자발적으로 wait 상태에 들어간것

     Ready :  어떤 다른 Task가 Signal을 날려서 일을 시키도록 신호받은 상태

 Status 두 가지 구분

Task_A()의 Status

     wait_signal :  Task_A()가 wait_signal()을 통해서 해당 Task가 기다리는 Signal을 넣어둠

    receive_signal : Task_B()가 Task_A()에게 일을 시키고 싶을 때 send_signal()을 함

                                    > Task_B 의 send_signal()이 된 signal > Task_A()의 receive_signal에 넣어둠

                                       > 처리 후 recive_signal 은 0 으로 초기화
>> send_signal() >  Task_A()가 signal을 받았을때

  if) receive_signal == wait_signal

        > wait_signal = 0 ( clear ) 

           :  (Scheduler입장)  Signal받음 > Ready 상태라고 판단

즉, Ready,runnig : wait_signal : 0 을 기다림

 

>> receive_siganal :  Task_A()가 Running Task가됨 > receive_signal :  해야 할 일을 판단 > receive_signal Clear

 


EX) 
Task가 0x3 signal을 기다린다면..

 

1. Wait Task : wait_signal 0x3 을 기다리고 , 그전의 receive_signal : 0

> Task_B 로부터 receive_signal : 0x3을 받음

   > wait_signal 0으로 초기화

Ready Task : wait_signal : 0을 기다림 , receive_signal : 0x3

> recive_signal 처리후 0 으로 초기화

   > waite_state == receive_signal == 0

Running Task : wait_signal, receive_signal 0

 

 wait_signal이 0인 것들 : 다음 scheduling의 대상이됨 // ready, running

   >  이 상태를 근거로 Scheduler가 Task Context Switching/ Scheduling

 Wait, Ready 상태의 Task의 SP : TCB에 저장되어 있는 값

but ) 현재 Running중이던 Task의 SP : TCB에 저장되어 있는 SP냐?  X

    > SP에서 Context를 빼서 > CPU Register에 넣으면서 SP update

        > 현재 Running중인 Task의 SP : CPU Register의 R13 (SP)

 

ex)

 

  • Task_A가 Ready 상태:
    • SP = 0x1000 (TCB에 저장됨).
  • Task_A가 Running 상태:
    • Scheduler는 TCB에서 SP 값을 읽어 CPU R13에 로드.
    • 실행 중 스택 변경: R13 값은 계속 업데이트됨.
  • Task_A에서 Task_B로 Context Switch:
    • Task_A의 SP(R13)를 TCB에 저장.
    • Task_B의 SP를 TCB에서 읽어 R13에 로드. 
  • Task_B > Task _ A context Switch
    • Task_B 의 SP(R13) > TCB 에 저장 >  STR R13, [TCB_B_SP]
    • 현재 PC의 레지스터 상태를 스택에 저장  > PUSH {R0-R12, LR} 
    • TCB_B에 스택 포인터 업데이트  > STR SP, [TCB_B_SP]
    • Task_A의 SP를 TCB에서 읽어 R13에 로드 >  LDR R13, [TCB_A_SP]
      • Task_A의 스택에서 레지스터 값 복원 > POP {R0-R12, LR} ;
        //스택에서 값을 꺼내 R0~R12, LR 을 PC 에로드함
    • Task_A 실행 시작 : BX LR  > 복원된 PC 값으로 점프

// PC(Program Counter)와 Task의 레지스터 공간 따로 있음 !

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

TCB 구조  (0) 2024.12.18
선점형 Multitasking  (0) 2024.12.14
Task Service  (1) 2024.12.14
Task 구조, signal  (0) 2024.12.12
Embedded Software는 무한 Loop  (0) 2024.12.11