Kernel Level의 Context Switching
현재의 Context잘 보전 > 다른 곳에 갔다 와서 하던 일 계속 진행 가능!
ARM의 Context > 그림1 > 이 녀석만 잘 저장해두면됨
> 해당 Task의 Stack에 저장
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의 스택에서 레지스터 값 복원 > POP {R0-R12, LR} ;
- 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 |