📄 os_cpu_a.asm
字号:
PUSH ES ; PUSH DS ;; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered MOV DS, AX ;; LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP MOV ES:[BX+2], SS ; 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] ; MOV SP, ES:[BX] ;; POP DS ; Load new task's context POP ES ; POPA ;; IRET ; Return to new task;_OSCtxSw ENDP PAGE ; /*$PAGE*/;*********************************************************************************************************; PERFORM A CONTEXT SWITCH (From an ISR); void OSIntCtxSw(void);; Note(s): 1) Upon entry,; OSTCBCur points to the OS_TCB of the task to suspend; OSTCBHighRdy points to the OS_TCB of the task to resume;; 2) The stack frame of the task to suspend looks as follows:;; OSTCBCur->OSTCBStkPtr ------> DS (Low memory); ES; DI; SI; BP; SP; BX; DX; CX; AX; OFFSET of task code address; SEGMENT of task code address; Flags to load in PSW (High memory);;; 3) The stack frame of the task to resume looks as follows:;; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory); ES; DI; SI; BP; SP; BX; DX; CX; AX; OFFSET of task code address; SEGMENT of task code address; Flags to load in PSW (High memory);*********************************************************************************************************_OSIntCtxSw PROC FAR; CALL FAR PTR _OSTaskSwHook ; Call user defined task switch hook; MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered MOV DS, AX ;; 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] ; MOV SP, ES:[BX] ;; POP DS ; Load new task's context POP ES ; POPA ;; IRET ; Return to new task;_OSIntCtxSw ENDP PAGE ; /*$PAGE*/;*********************************************************************************************************; HANDLE TICK ISR;; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS; tick rate of 18.20648 Hz. Thus every 11th time, the normal DOS tick handler is called.; This is called chaining. 10 times out of 11, however, the interrupt controller on the PC; must be cleared to allow for the next interrupt.;; Arguments : none;; Returns : none;; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.;; Save all registers on the current task's stack;; OSIntNesting++;; if (OSIntNesting == 1) {; OSTCBCur->OSTCBStkPtr = SS:SP; }; OSTickDOSCtr--;; if (OSTickDOSCtr == 0) {; OSTickDOSCtr = 11;; INT 81H; Chain into DOS every 54.925 mS; (Interrupt will be cleared by DOS); } else {; Send EOI to PIC; Clear tick interrupt by sending an End-Of-Interrupt to the 8259; PIC (Priority Interrupt Controller); }; OSTimeTick(); Notify uC/OS-II that a tick has occured; OSIntExit(); Notify uC/OS-II about end of ISR; Restore all registers that were save on the current task's stack;; Return from Interrupt;;*********************************************************************************************************;_OSTickISR PROC FAR; PUSHA ; Save interrupted task's context PUSH ES PUSH DS; MOV AX, SEG(_OSIntNesting) ; Reload DS MOV DS, AX INC BYTE PTR DS:_OSIntNesting ; Notify uC/OS-II of ISR; CMP BYTE PTR DS:_OSIntNesting, 1 ; if (OSIntNesting == 1) JNE SHORT _OSTickISR1 MOV AX, SEG(_OSTCBCur) ; Reload DS 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 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.;_OSTickISR3: CALL FAR PTR _OSTimeTick ; Process system tick; CALL FAR PTR _OSIntExit ; Notify uC/OS-II of end of ISR; POP DS ; Restore interrupted task's context POP ES POPA; IRET ; Return to interrupted task;_OSTickISR ENDP;; END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -