task의 정보를 담고있는 구조체
OSTCBStkPtr : top-of-stack을 가르키는 포인터
OSTCBExtPtr*
OSTCBStkBottom* : bottom-of-stack을 가르키는 포인터
OSTCBStkSize : stack size
OSTCBNext, OSTCBPrev : OS_TCB list의 앞/뒤의 TCB를 가르키는 포인터.
OSTCBDly
OSTCBStat : task state
OSTCBPrioTblp[] : task들을 관리하는 테이블, 실행중인 task의 주소가 할당되어있다.
OSTCBHighRdy : 가장 높은 우선순위를 갖는 task를 가르킨다.
OSTCBCur : 현재 실행중인 task를 나타낸다.
OSTCBFreeList 가장 앞의 있는 task가 실행되면 OSTCBList의 끝에 추가된다.
void OSSched (void){
INT8U y;
OS_ENTER_CRITICAL();
/*
OSLockNesting : 스케줄링 락
OSIntNesting : 인터럽트 설정 여부
0이면 사용중인 것
*/
if((OSLockNesing | OSIntNesting) == 0) { //스케줄링 잠금 해제 상태
/*우선순위가 가장 높은 task를 찾음*/
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
/*현재 실행 TASK와 우선순위 높은 TASK가 같지않으면 SWITCH가 필요함.*/
if (OSPrioHighRdy != OSPrioCur){
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCTR++;
OS_TASK_SW(); //task switching 함수
}
}
OS_EXIT_CRITICAL();
}
ISR 수준의 스케줄링은 OSIntExit()에 의해 수행된다.
OSTCBHighRdy는 다음에 선점될 task의 TCB를 가르킨다.
높은 우선순위에 있는 task의 stack을 CPU로 LOAD한 후 현재 선점되어있는 task의 stack에 저장한다.
가장 높은 우선순위를 가진 task의 stack의 register들은 pop되고 SP는 현재 선점된 우선순위가 높은 task의 stack top을 가르키게된다.
void OSIntEnter(void){
/*인터럽트 활성화/비활성화 함수*/
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
void OSIntExit(void){
OS_ENTER_CRITICAL();
if((--OSIntNesting | OSLockNesting) == 0){
/*
가장 높은 task를 찾은 다음 OSPrioHighRdy에 넣는다.
*/
OSIntExitY = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((OSRdyGrp] + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
if(OSPrioHighRedy != OSPrioCur){
/*
현재 실행되는 task가 현재 가장 높은 task보다 우선순위가 낮으면
context_switch가 발생한다.
*/
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++;
OSIntCtxSw();
|
}
OS_EXIT_CRITICAL();
|