📄 os_cpu_a.a30
字号:
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
; (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
; All Rights Reserved
;
;********************************************************************************************************
;
; Port to Mitsubishi M16C/60 Series
;
; (c) Florian Stassen
; started 2003-01-18
;
;********************************************************************************************************
; interne Funktionen
.glb _OSStartHighRdy
.glb _OSCtxSw
.glb _OSIntCtxSw
.glb _OSTickISR
.glb _OSTickISR1
; externe Funktionen
.glb _OSIntEnter
.glb _OSIntExit
.glb _OSTimeTick
.glb _OSTaskSwHook
; externe Variablen
.glb _OSIntNesting ; declared as INT8U
.glb _OSPrioHighRdy ; declared as INT8U
.glb _OSPrioCur ; declared as INT8U
.glb _OSRunning ; declared as INT8U
.glb _OSTCBCur ; declared as OS_TCB *
.glb _OSTCBHighRdy ; declared as OS_TCB *
.section program,align
.PAGE ; /*$PAGE*/
;*********************************************************************************************************
; Start High Ready Task
; void OSStartHighRdy(void)
;
; Description: This function is called from OSStart()
;
; Arguments : none
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> R0 (Low memory)
; R1
; R2
; R3
; A0
; A1
; SB
; FB
; PC
; FLG/PC (High memory)
;
; Note : OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
.ALIGN
_OSStartHighRdy:
JSR _OSTaskSwHook
MOV.W _OSTCBHighRdy, A0 ; SP = OSTCBHighRdy->OSTCBStkPtr
LDC [A0], SP
MOV.B #01H, _OSRunning ; OSRunning = TRUE
POPM R0,R1,R2,R3,A0,A1,SB,FB
REIT
.PAGE ; /*$PAGE*/
;*********************************************************************************************************
; Context Switch
; void OSCtxSw(void)
;
; Description: This function is called from OSSched()
;
; Arguments : none
;
; Note: OSCtxSw() is always called in User-Mode (USP active),
; so there are no problems with USP and ISP.
;
; Note(s): 1) You must map the address of OSCtxSw() to interrupt #0 in the vector table
;
; 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 -> PC (Low memory)
; FLG/PC (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> R0 (Low memory)
; R1
; R2
; R3
; A0
; A1
; SB
; FB
; PC
; FLG/PC (High memory)
;
;*********************************************************************************************************
.ALIGN
_OSCtxSw:
PUSHM R0,R1,R2,R3,A0,A1,SB,FB
MOV.W _OSTCBCur, A0 ; OSTCBCur->OSTCBStkPtr = SP
STC SP, [A0]
JSR _OSTaskSwHook ; OSTaskSwHook()
MOV.W _OSTCBHighRdy, _OSTCBCur ; OSTCBCur = OSTCBHighRdy
MOV.B _OSPrioHighRdy, _OSPrioCur ; OSPrioCur = OSPrioHighRdy
MOV.W _OSTCBHighRdy, A0 ; SP = OSTCBHighRdy->OSTCBStkPtr
LDC [A0], SP
POPM R0,R1,R2,R3,A0,A1,SB,FB ; Restore all processor registers from the new task's stack
REIT
.PAGE ; /*$PAGE*/
;*********************************************************************************************************
; Context Switch from ISR
; void OSIntCtxSw(void)
;
; Description: This function is called from OSIntExit()
;
; Arguments : none
;
; Note This function is always called from inside an ISR, so ISP is used.
; On first ISR the registers of the current task are stored on the interrupt stack (ISP).
; OSIntCtxSw() has to move the registers from the interrupt stack to the
; user stack and process the second half of a normal context switch.
;
; 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:
; (ISP active)
;
; OSTCBCur->OSTCBStkPtr ------> R0 (Low memory)
; R1
; R2
; R3
; A0
; A1
; SB
; FB
; PC
; FLG/PC (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
; (USP active)
;
; OSTCBHighRdy->OSTCBStkPtr --> R0 (Low memory)
; R1
; R2
; R3
; A0
; A1
; SB
; FB
; PC
; FLG/PC (High memory)
;
;*********************************************************************************************************
.ALIGN
_OSIntCtxSw:
MOV.W _OSTCBCur, A0 ; SP = OSTCBCur->OSTCBStkPtr
LDC [A0], SP ; SP is ISP
fset U ; switch to USP
mov.w #10,r3 ; move 10 words
mov.b #0,r1h
mov.w [a0],a0 ; R1H & A0 = ISP = Src Address
stc sp,a1 ; A1 = USP
sub.w #20,a1 ; 10 words space, A1 = Dest Address
ldc a1,sp ; new USP
smovf.w ; String Move Forward
; A0 contains corrected ISP
ldc a0,isp
; now all registers and PC and FLG are on the user stack
; and SP (=USP) point to the correct address
MOV.W _OSTCBCur, A0 ; OSTCBCur->OSTCBStkPtr = SP
STC SP, [A0]
; here we have a normal enviroment for a context switch
JSR _OSTaskSwHook ; OSTaskSwHook()
MOV.W _OSTCBHighRdy, _OSTCBCur ; OSTCBCur = OSTCBHighRdy
MOV.B _OSPrioHighRdy, _OSPrioCur ; OSPrioCur = OSPrioHighRdy
MOV.W _OSTCBHighRdy, A0 ; SP = OSTCBHighRdy->OSTCBStkPtr
LDC [A0], SP
POPM R0,R1,R2,R3,A0,A1,SB,FB ; Restore all processor registers from the new task's stack
REIT
.PAGE ; /*$PAGE*/
;*********************************************************************************************************
; Time ticker ISR
; void OSTickISR(void)
;
; Description: This function is invoked by hardware timer
;
; Arguments : none
;
; Note(s) : 1) Pseudo code:
;
; Save all registers
; OSIntNesting++
; if (OSIntNesting == 1) {
; OSTCBCur->OSTCBStkPtr = SP
; }
; OSTimeTick();
; OSIntExit();
; Restore all registers
; Return from interrupt;
;*********************************************************************************************************
.ALIGN
_OSTickISR:
PUSHM R0,R1,R2,R3,A0,A1,SB,FB ; Save current task's registers
jsr _OSIntEnter ; OSIntEnter()
CMP.B #1,_OSIntNesting ; if (OSIntNesting == 1) {
JNE _OSTickISR1
MOV.W _OSTCBCur, A0 ; OSTCBCur->OSTCBStkPtr = SP
STC SP, [A0]
_OSTickISR1:
JSR _OSTimeTick ; OSTimeTick()
JSR _OSIntExit ; OSIntExit()
POPM R0,R1,R2,R3,A0,A1,SB,FB ; Restore registers from the new task's stack
REIT
;*********************************************************************************************************
.END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -