📄 os_cpu_a.asm
字号:
BCLR IEN ; Disable interrupts
EXTP #PAG OSTCBHighRdy,#02h ; OSTCBCur = OSTCBHighRdy;
MOV R12,POF OSTCBHighRdy ; 间接寻址,取OSTCBHighRdy所指向地址的页面偏移
MOV R13,POF (OSTCBHighRdy+2) ; 间接寻址,取OSTCBHighRdy所指向地址的页号
EXTP #PAG OSTCBCur,#02h
MOV POF (OSTCBCur),R12 ;
MOV POF (OSTCBCur+2),R13
EXTP R13,#02h ; pStack = OSTCBCur->OSTCBStkPtr;
MOV R14,[R12+] ; Load Offset pointer
MOV R15,[R12] ; Load Page pointer
; ; Load Task's Context from TCB
EXTP R15,#02h ; Start Of Task USR Stack Offset
MOV R0,[R14+#0AH] ; Task R0
MOV R1,[R14+#08H] ; Task DPP1
EXTP R15,#02h
MOV R2,[R14+#04H] ; Task IP
MOV R3,[R14+#02H] ; Task CSP
MOV SP,#DPP3:TOS ; 初始化系统堆栈
MOV DPP1,R1 ; Start Of Task USER Stack Page
PUSH R3 ; Load "saved" CSP on System Stack
PUSH R2 ; Load "saved" IP on System Stack
%RestoreContext() ; Restore context.
BSET IEN ; Enable interrupts
RETS ; Execute Task
OSStartHighRdy ENDP
;********************************************************************************************************
; 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 system stack frame of the task to suspend looks as follows:
; SYSTEM STACK AREA
; SP -> +00 OFFSET of task to suspend (Low memory)
; +02 SEGMENT of task to suspend
; +04 PSW of task to suspend (High memory)
;
; 3) The user stack frame of the task to resume looks as follows:
;
; TASK STACK AREA (High Memory)
; +12 TASK DATA PARAMETER PAGE pointer of task
; +10 TASK DATA PARAMETER OFFSET pointer of task
; +0E SEGMENT of task code address
; +0C OFFSET of task code address
; +0A USER STACK OFFSET POINTER (R0) of task
; +08 USER STACK PAGE POINTER (DPP1) of task
; +06 PSW flags of task
; +04 OFFSET of task return address
; 02 SEGMENT of task return address
; OSTCBHighRdy->OSTCBStkPtr --> 0
; -02 R[1 ..15] General Purpose registers of task
; -20 CP Context pointer of task
; -22 DPP3 Data page pointer 3 of task
; -24 DPP2 Data page pointer 2 of task
; -26 DPP0 Data page pointer 0 of task
; -28 MDC Multiply/Divide Control of task
; -2A MDH Multiply/Divide High register of task
; -2C MDL Multiply/Divide Low register of task (Low Memory)
;********************************************************************************************************
OSCtxSw PROC INTERRUPT UCOS_OSCtxSw = 0x50
BCLR IEN ; Disable interrupts
%SaveContext() ; Save Register Context
POP R2 ; Get "current" IP
POP R1 ; Get "current" CSP
POP R3 ; Get "current" PSW
EXTP #PAG OSTCBCur,#02h ; pStack = OSTCBCur->OSTCBStkPtr
MOV R8,POF (OSTCBCur) ; 堆栈指针页号:偏移量 = R9:R8
MOV R9,POF (OSTCBCur+2)
EXTP R9,#02h
MOV R6,[R8+]
MOV R7,[R8]
EXTP R7,#03h
MOV [R6+#02h],R1 ; Task CSP
MOV [R6+#04h],R2 ; Task IP
MOV [R6+#06h],R3 ; Task STATUS
MOV R4,#TOS ; Get the top of the System Stack
MOV R5,SP
_OSCtxSwSave:
CMP R4,R5 ; Compare if Pointer is equal to Current Stack position on system stack
JMPA cc_EQ,_OSCtxSwSaveEnd ; Exit the Loop if they are equal
SUB R4,#02H ; Decrement pointer of System Stack
EXTS #0,#1
MOV R3,[R4] ; Read data from system stack
MOV [-R0],R3 ; Save System Stack Value to the Task Satck
JMPA cc_UC,_OSCtxSwSave ; Do loop again
_OSCtxSwSaveEnd:
MOV R4,DPP1 ; Get "current" DPP1
EXTP R7,#03h
MOV [R6+#08H],R4 ; Task DPP1
MOV [R6+#0AH],R0 ; Task R0
MOV [R6+#0CH],R5 ; Task SP
CALLS SEG(OSTaskSwHook),SOF(OSTaskSwHook) ; Call user defined task switch hook
_ADDR01:
EXTP #PAG OSTCBHighRdy,#02h ; Get the stack pointer of the task to resume
MOV R8,POF OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy
MOV R9,POF (OSTCBHighRdy+2)
EXTP #PAG OSTCBCur,#02h
MOV POF (OSTCBCur),R8
MOV POF (OSTCBCur+2),R9
EXTP #PAG OSPrioHighRdy,#01h ; OSPrioCur = OSPrioHighRdy;
MOVB RL1,POF OSPrioHighRdy
EXTP #PAG OSPrioCur,#01h
MOVB POF OSPrioCur,RL1
EXTP R9,#02h ; R7:R6 = OSTCBHighRdy->OSTCBStkPtr
MOV R6,[R8+]
MOV R7,[R8]
EXTP R7,#03h
MOV R5,[R6+#0Ch] ; Get Task SP
MOV R0,[R6+#0Ah] ; Get Task R0
MOV R4,[R6+#08h] ; Get Task DPP1
MOV DPP1,R4 ; Write "current task" DPP1
MOV SP,R5 ; Replace the Task System Stack Pointer
MOV R4,#TOS ; Get the top of the System Stack
_OSCtxSwRestore:
CMP R4,R5 ; Compare if Pointer is equal to Satck Pointer (SP)
JMPA cc_EQ,_OSCtxSwRestoreEnd ; Loop if not equal
MOV R3,[R0+] ; Read value in the task stack
EXTS #0,#1
MOV [R5],R3 ; Replace System Stack Value
ADD R5,#02H ; Increment pointer of System Stack
JMPA cc_UC,_OSCtxSwRestore ; Do loop again
_OSCtxSwRestoreEnd:
EXTP R7,#03h ; Load this task's interrupt context on the system stack
MOV R3,[R6+#06h] ; Get Task PSW
MOV R2,[R6+#04h] ; Get Task IP
MOV R1,[R6+#02h] ; Get Task CSP
PUSH R3 ; Replace PSW on System stack
PUSH R1 ; Replace CSP on system Stack
PUSH R2 ; Replace IP on System Stack
%RestoreContext() ; Restore all processor registers from the new task's stack
BSET IEN ; Enable interrupts
RETI ; Return to new task
; Return to new task
OSCtxSw ENDP
;********************************************************************************************************
; 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 system stack frame of the task to suspend looks as follows:
; SYSTEM STACK AREA
; SP -> +0 OFFSET of task to suspend (Low memory)
; +2 SEGMENT of task to suspend
; +4 PSW of task to suspend (High memory)
;
; 3) The user stack frame of the task to resume looks as follows:
;
; TASK STACK AREA (High Memory)
; +12 TASK DATA PARAMETER PAGE pointer of task
; +10 TASK DATA PARAMETER OFFSET pointer of task
; +0E SEGMENT of task code address
; +0C OFFSET of task code address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -