📄 os_cpu_a.asm
字号:
OSCtxSw PROC INTERRUPT UCOS_OSCtxSw = 0x10
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) ; pStack = R9:R8
MOV R9,POF (OSTCBCur+2)
EXTS R9,#02h
MOV R6,[R8+]
MOV R7,[R8]
EXTS R7,#03h ; Save this task's interrupt context in task user stack
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
EXTS 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
EXTS R9,#02h ; R7:R6 = OSTCBHighRdy->OSTCBStkPtr
MOV R6,[R8+]
MOV R7,[R8]
EXTS 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:
EXTS 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
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)
; +14 TASK DATA PARAMETER SEGMENT pointer of task
; +12 TASK DATA PARAMETER OFFSET pointer of task
; +10 SEGMENT of task code address
; +0E OFFSET of task code address
; +0C SP of System stack of task
; +0A USER STACK OFFSET POINTER (R0) of task
; +08 USER STACK PAGE POINTER (DPP1) of task
; +06 PSW of task
; +04 OFFSET of task return address (IP)
; +02 SEGMENT of task return address (CSP)
; 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
; -2E PSW PSW of the interrupting task when task have been interrupted
;********************************************************************************************************
OSIntCtxSw PROC ;INTERRUPT NOT_A_ISR_JUST_TO_REMOVE_COMPILER_WARNING = 0x11
BCLR IEN ; Disable interrupts
ADD DPP3:SP,#8h ; Remove From System Stack the calls to OSIntCtxSw and OsIntExit
NOP ; Ignore calls to OSIntExit,OSIntCtxSw and locals.
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) ; pStack = R9:R8
MOV R9,POF (OSTCBCur+2)
EXTS R9,#02h
MOV R6,[R8+]
MOV R7,[R8]
EXTS R7,#03h ; Save this task's interrupt context in task user stack
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
_OSIntCtxSwSave:
CMP R4,R5 ; Compare if Pointer is equal to Current Stack position on system stack
JMPA cc_EQ,_OSIntCtxSwSaveEnd ; 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,_OSIntCtxSwSave ; RE-Loop again
_OSIntCtxSwSaveEnd:
MOV R4,DPP1 ; Get "current" DPP1
EXTS 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
_ADDR02:
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
EXTS R9,#02h ; R7:R6 = OSTCBHighRdy->OSTCBStkPtr
MOV R6,[R8+]
MOV R7,[R8]
EXTS 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
_OSIntCtxSwRestore:
CMP R4,R5 ; Compare if Pointer is equal to Satck Pointer (SP)
JMPA cc_EQ,_OSIntCtxSwRestoreEnd ; 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,_OSIntCtxSwRestore ; Loop again
_OSIntCtxSwRestoreEnd:
EXTS 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
OSIntCtxSw ENDP
;********************************************************************************************************
; HANDLE TICK ISR
; void OSTickISR (void)
;
; Description: This function is called every 10ms
;
; Arguments : none
;
; Returns : none
;
; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
; Disable interrupts;
; Save all registers on the current task's stack;
; OSIntEnter();
; OSTimeTick(); Notify uC/OS-II that a tick has occured
; Clear RTC or Timer Interrupt Response Bit
; OSIntExit(); Notify uC/OS-II about end of ISR
; Restore all registers that were save on the current task's stack;
; Enable interrupts;
; Return from Interrupt;
;********************************************************************************************************
;
;OSTickISR works normally :henry ;
;********************************************************************************************************
OSTickISR PROC INTERRUPT UCOS_OSTickISR = 0x22
BCLR IEN ; Disable interrupts
%SaveContext() ; Save current task's context
CALL OSIntEnter
CALL OSTimeTick
BCLR GPT12E_T2IC_IR ; Clear Timer 2 Interrupt Response Bit
CALL OSIntExit
%RestoreContext() ; Restore new task's context
BSET IEN ; Enable interrupts
RETI ; Return to interrupted task
OSTickISR ENDP
UCOS_C16X ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -