Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

LIB 2: Difference between revisions

From ZeroWiki
imported>Unknown
No edit summary
 
(Repair MoniWiki formatting after migration)
Line 1: Line 1:
이번엔 타이머 인터럽트를 통해 컨텍스트 스위칭이 이루어지는 인터럽트 서비스 루틴에 관한  
이번엔 타이머 인터럽트를 통해 컨텍스트 스위칭이 이루어지는 인터럽트 서비스 루틴에 관한 <br />
코드를 살펴볼까 한다.
코드를 살펴볼까 한다.
씨에서는 interrupt란 예약어로 함수를 인터럽트 콜이 가능한 함수를 만들 수 있다.
씨에서는 interrupt란 예약어로 함수를 인터럽트 콜이 가능한 함수를 만들 수 있다.<br />
이럴 경우 컴파일을 해 보면 펑션의 호출이 RET가 아닌 IRET로 끝나게 된다.
이럴 경우 컴파일을 해 보면 펑션의 호출이 RET가 아닌 IRET로 끝나게 된다.<br />
그럴 경우 IRET 로 끝날 경우 [[CS]]:[[IP]] FLAGS를 스택에서 PUSH하게 된다.
그럴 경우 IRET 로 끝날 경우 [[CS]]:[[IP]] FLAGS를 스택에서 PUSH하게 된다.<br />
PS RET로 끝날 경우 [[CS]]:[[IP]]만 PUSH하게 된다.
PS RET로 끝날 경우 [[CS]]:[[IP]]만 PUSH하게 된다.<br />


하하 넘 오래간만에 봤더니 나도 무슨 함순지 모르는 것이 있군..
하하 넘 오래간만에 봤더니 나도 무슨 함순지 모르는 것이 있군..<br />


  void interrupt LIB_ISR(...){
  void interrupt LIB_ISR(...){
Line 38: Line 38:
  }
  }


인터럽트 서비스 루틴을 초기화 해주는 함수로  
인터럽트 서비스 루틴을 초기화 해주는 함수로 <br />
시작 태스크를 초기화 하고 인터럽트 벡터 테이블에서 타이머의 [[CS]]:[[IP]]의
시작 태스크를 초기화 하고 인터럽트 벡터 테이블에서 타이머의 [[CS]]:[[IP]]의
부분을 위의 LIB_ISR로 바꿔준다.
부분을 위의 LIB_ISR로 바꿔준다.
Line 83: Line 83:
  }
  }
이제 여기서부터 실제적인 컨텍스트 스위칭이 일어난다.
이제 여기서부터 실제적인 컨텍스트 스위칭이 일어난다.
우선 가장 상위의 태스크를 찾겠지?? 아마 그건
우선 가장 상위의 태스크를 찾겠지?? 아마 그건 <br />
High_Task 로 지정된 태스크일 것이다. 그 태스크의 스택 위치를 찾아 스택 포인트를 바꿔준다.
High_Task 로 지정된 태스크일 것이다. 그 태스크의 스택 위치를 찾아 스택 포인트를 바꿔준다.


Line 106: Line 106:
----
----
[[REAL_LIBOS]]
[[REAL_LIBOS]]

Revision as of 14:01, 26 March 2026

이번엔 타이머 인터럽트를 통해 컨텍스트 스위칭이 이루어지는 인터럽트 서비스 루틴에 관한
코드를 살펴볼까 한다. 씨에서는 interrupt란 예약어로 함수를 인터럽트 콜이 가능한 함수를 만들 수 있다.
이럴 경우 컴파일을 해 보면 펑션의 호출이 RET가 아닌 IRET로 끝나게 된다.
그럴 경우 IRET 로 끝날 경우 CS:IP FLAGS를 스택에서 PUSH하게 된다.
PS RET로 끝날 경우 CS:IP만 PUSH하게 된다.

하하 넘 오래간만에 봤더니 나도 무슨 함순지 모르는 것이 있군..

void interrupt LIB_ISR(...){
	LIB_ENTER_CRITICAL();
	(*oldtimer)();
	LIB_INT_COUNT++;
	/////////////// Decrease Time Dly
	for ( int i = 0 ; i < suspend_tcb_ptr + 1; i++ ){
		pSuspend_heap[i]->delay--;
		if ( High_Task->priority < pSuspend_heap[i]->priority && pSuspend_heap[i]->delay < 0 ) {
			pSuspend_heap[i]->delay = 0;
			LIB_resume_task(pSuspend_heap[i]->priority);
		}
	}
	/////////////// CONTEXT SWITCHING
	asm {
			MOV S_SEG,SS
			MOV S_OFF,SP
	}
	High_Task->StackSeg = S_SEG;
	High_Task->StackOff = S_OFF;
	LIB_Schedul();
	S_SEG = High_Task->StackSeg;
	S_OFF = High_Task->StackOff;
	asm {
			MOV SS,S_SEG
			MOV SP,S_OFF
	}
	///////////////////////////////////
	LIB_EXIT_CRITICAL();
}

인터럽트 서비스 루틴을 초기화 해주는 함수로
시작 태스크를 초기화 하고 인터럽트 벡터 테이블에서 타이머의 CS:IP의 부분을 위의 LIB_ISR로 바꿔준다.

void  LIB_INIT_ISR(){
	LIB_INT_NESTING = 0;
	INT16U	Time_Vect = 0x08 * 4;
	High_Task = &START_TCB;
	START_TCB.priority = 0;
	START_TCB.StackSeg = 0;
	START_TCB.StackOff = 0;

겟 벡터에서 0x08 번째의 타이머 백터 그리고 4바이트가 필요해서 *4를 해서 타이머 벡터의 위치를 구해 그 부분의 타이머를 저장해 둔다..만약의 복귀를 위해..^^;

	// Get Vecter Table oldtimer
	asm {
	MOV BX,Time_Vect
	MOV AX,0
	MOV DS,AX
	MOV SI,BX
	MOV AX,DS:[SI]
	MOV DX,DS:[SI+2]
	MOV DI,offset oldtimer
	MOV BX,seg    oldtimer
	MOV ES,BX
	MOV ES:[DI],AX
	MOV ES:[DI+2],DX
	}

이제 셋 타이머를 해준다...

	// Set Timer Vector Table
	asm {
	MOV AX,0
	MOV ES,AX
	MOV DI,Time_Vect
	MOV AX,offset LIB_ISR
	MOV ES:[DI],AX
	MOV AX,seg LIB_ISR
	MOV ES:[DI+2],AX
	}
}

이 프로그램이 복귀 가능하게 만들 경우 TSR을 이용한다..근데 지금은 필요 없는듯...

void LIB_TSR() {
    union REGS regs;
    regs.x.dx=4000;
    int86(0x27,&regs,&regs);
}

이제 여기서부터 실제적인 컨텍스트 스위칭이 일어난다. 우선 가장 상위의 태스크를 찾겠지?? 아마 그건
High_Task 로 지정된 태스크일 것이다. 그 태스크의 스택 위치를 찾아 스택 포인트를 바꿔준다.

void interrupt LIB_context_sw(){
	LIB_ENTER_CRITICAL();
	/////////////// CONTEXT SWITCHING
	asm {
			MOV S_SEG,SS
			MOV S_OFF,SP
	}
	High_Task->StackSeg = S_SEG;
	High_Task->StackOff = S_OFF;
	LIB_Schedul();
	S_SEG = High_Task->StackSeg;
	S_OFF = High_Task->StackOff;
	asm {
			MOV SS,S_SEG
			MOV SP,S_OFF
	}
	///////////////////////////////////
	LIB_EXIT_CRITICAL();

REAL_LIBOS