void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE) {
y = OSUnMapTbl[OSRdyGrp]; /* 找到最高优先级任务优先级号 */
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* 指向已就绪的最高优先级任务TCB */
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy(); /* 启动任务 */
}
}
_OSStartHighRdy PROC FAR
MOV AX, SEG _OSTCBHighRdy ; 重装载 DS
MOV DS, AX ;
;
CALL FAR PTR _OSTaskSwHook ; 调用用户自定义函数
;
MOV AL, 1 ; OSRunning = TRUE
MOV BYTE PTR DS:_OSRunning, AL ;多任务运行已经要开始了
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX+0] ;
;
POP DS ; Load task's context
POP ES
POPA
;
IRET ; Run task
_OSStartHighRdy ENDP
_OSCtxSw PROC FAR
;
PUSHA ;当前任务相关寄存器保存
PUSH ES ;
PUSH DS ;
;
MOV AX, SEG _OSTCBCur ;重装在当起任务TCB的指针以防被改变
MOV DS, AX ;
;
LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;当前任务堆栈指针存往 TCB 中
MOV ES:[BX+0], SP ;
;
CALL FAR PTR _OSTaskSwHook ; Call user defined task switch hook
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL ;
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;取出就绪即运行任务堆栈指针改写到SS:SP中
MOV SP, ES:[BX] ;
;
POP DS ;恢复新任务的上下文
POP ES ;
POPA ;
;
IRET ; Return to new task
;
_OSCtxSw ENDP
_OSTickISR PROC FAR
;
PUSHA ;中断进,保存CPU相关寄存器
PUSH ES
PUSH DS
;
MOV AX, SEG(_OSIntNesting) ;取得OSIntNesting变量的段地址
MOV DS, AX
INC BYTE PTR DS:_OSIntNesting ; OSIntNesting++
CMP BYTE PTR DS:_OSIntNesting, 1 ; if (OSIntNesting == 1)
JNE SHORT _OSTickISR1
MOV AX, SEG(_OSTCBCur) ;第一层中断则保存好当前任务堆栈指针
MOV DS, AX
LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
_OSTickISR1:
MOV AX, SEG(_OSTickDOSCtr) ; Reload DS
MOV DS, AX
DEC BYTE PTR DS:_OSTickDOSCtr
CMP BYTE PTR DS:_OSTickDOSCtr, 0
JNE SHORT _OSTickISR2 ; Every 11 ticks (~199.99 Hz), chain into DOS
;
MOV BYTE PTR DS:_OSTickDOSCtr, 11 ;若达到DOS的中断则调到0x81进行中断处理
INT 081H ; Chain into DOS's tick ISR
JMP SHORT _OSTickISR3
_OSTickISR2:
MOV AL, 20H ; Move EOI code into AL.
MOV DX, 20H ; Address of 8259 PIC in DX.
OUT DX, AL ; Send EOI to PIC if not processing DOS timer.
;EOI-->end of interrupt,清中断
_OSTickISR3:
CALL FAR PTR _OSTimeTick ; Process system tick
;
CALL FAR PTR _OSIntExit ;中断结束,退出
;
POP DS ; Restore interrupted task's context
POP ES
POPA
;
IRET ; Return to interrupted task
;
_OSTickISR ENDP
;
END
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |