📄 os_cpu_a.asm
字号:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
; All Rights Reserved
;
;
; 80x86/80x88 Specific code
; LARGE MEMORY MODEL
;
; Borland C/C++ V4.51
; (IBM/PC Compatible Target)
;
; File : OS_CPU_A.ASM
; By : Jean J. Labrosse
;********************************************************************************************************
[SECTION .text]
[BITS 32]
;********************************************************************************************************
; global and EXTERNAL REFERENCES
;********************************************************************************************************
global OSTickISR
global OSStartHighRdy
global OSCtxSw
global OSIntCtxSw
extern OSIntExit
extern OSTimeTick
extern OSTaskSwHook
extern OSIntNesting ;:BYTE
extern OSTickDOSCtr ;:BYTE
extern OSPrioHighRdy ;:BYTE
extern OSPrioCur ;:BYTE
extern OSRunning ;:BYTE
extern OSTCBCur ;:DWORD
extern OSTCBHighRdy ;:DWORD
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
; ES
; EDI
; ESI
; EBP
; ESP
; EBX
; EDX
; ECX
; EAX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW
; OFFSET of task code address
; SEGMENT of task code address
; OFFSET of 'pdata'
; SEGMENT of 'pdata' (High memory)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
OSStartHighRdy:
CALL OSTaskSwHook ; Call user defined task switch hook
;
MOV AL, 1 ; OSRunning = TRUE;
MOV BYTE [OSRunning], AL ; (Indicates that multitasking has started)
MOV EBX, [OSTCBHighRdy]
MOV ESP, [EBX] ; 切换任务栈
;
POP DS ; Load task's context
POP ES ;
POPAD
;
IRETD ; Run task
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level)
; void OSCtxSw(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:
;
; SP -> OFFSET of task to suspend (Low memory)
; SEGMENT of task to suspend
; PSW of task to suspend (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
; ES
; EDI
; ESI
; EBP
; ESP
; EBX
; EDX
; ECX
; EAX
; ADDRESS of task code
; Flags to load in EPSW (High memory)
;*********************************************************************************************************
OSCtxSw: ;任务级任务切换
;
PUSHAD ; Save current task's context
PUSH ES ;
PUSH DS ;
MOV EBX, [OSTCBCur]
MOV [EBX], ESP ; OSTCBCur->OSTCBStkPtr = ESP
CALL OSTaskSwHook ; Call user defined task switch hook
MOV EAX, [OSTCBHighRdy] ; OSTCBCur <= OSTCBHighRdy
MOV [OSTCBCur], EAX ;
MOV AL, [OSPrioHighRdy] ; OSPrioCur <= OSPrioHighRdy
MOV [OSPrioCur], AL ;
MOV EBX, [OSTCBHighRdy] ; ESP = OSTCBHighRdy->OSTCBStkPtr
MOV ESP, [EBX]
POP DS ; Load new task's context
POP ES ;
POPAD
IRETD ; Return to new task
;
;*********************************************************************************************************
; 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:
;
CALL OSTaskSwHook ; Call user defined task switch hook
;
MOV EAX, [OSTCBHighRdy] ; OSTCBCur = OSTCBHighRdy
MOV [OSTCBCur], EAX ;
;
MOV AL, [OSPrioHighRdy] ; OSPrioCur = OSPrioHighRdy
MOV [OSPrioCur], AL
;
MOV EBX, [OSTCBHighRdy] ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV ESP, [EBX] ;
;
POP DS ; Load new task's context
POP ES ;
POPAD ;
;
IRETD ; Return to new task
;
;*********************************************************************************************************
; 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:
;
PUSHAD ; Save interrupted task's context
PUSH ES
PUSH DS
INC BYTE [OSIntNesting] ; Notify uC/OS-II of ISR
CMP BYTE [OSIntNesting], 1 ; if (OSIntNesting == 1)
JNE SHORT _OSTickISR1
MOV EBX, [OSTCBCur]
MOV [EBX], ESP ; OSTCBCur->OSTCBStkPtr = (SS):ESP
_OSTickISR1:
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 OSTimeTick ; Process system tick
;
CALL OSIntExit ; Notify uC/OS-II of end of ISR
;
POP DS ; Restore interrupted task's context
POP ES
POPAD
;
IRETD ; Return to interrupted task
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -