📄 os_cpu_a.s
字号:
MOVEM.L D0-D7/A0-A6,(A7) ; Save the registers of the current task
MOVE.L (_OSTCBCur),A1 ; Save the stack pointer in the suspended task TCB
MOVE.L A7,(A1)
JSR _OSTaskSwHook ; Invoke user defined context switch hook
MOVE.L (_OSTCBHighRdy),A1 ; OSTCBCur = OSTCBHighRdy
MOVE.L A1,(_OSTCBCur)
MOVE.L (A1),A7 ; Get the stack pointer of the task to resume
MOVE.B (_OSPrioHighRdy),D0 ; OSPrioCur = OSPrioHighRdy
MOVE.B D0,(_OSPrioCur)
MOVEM.L (A7),D0-D7/A0-A6 ; Restore the CPU registers
LEA 60(A7),A7
RTE ; Run task
;******************************************************************************************
; INTERRUPT LEVEL CONTEXT SWITCH
;
;
; Description : This function is provided for backward compatibility.
;
; Arguments : none
;
; Note(s) : 1) The stack frame upon entry:
;
; SP + 0 ----> Return PC of OSIntCtxSw() Low Memory
; + 4 Return PC of OSIntExit()
; + 8 D0 (H)
; + 12 D1 (H)
; + 16 D2 (H)
; + 20 D3 (H)
; + 24 D4 (H)
; + 28 D5 (H)
; + 32 D6 (H)
; + 36 D7 (H)
; + 40 A0 (H)
; + 44 A1 (H)
; + 48 A2 (H)
; + 52 A3 (H)
; + 56 A4 (H)
; + 60 A5 (H)
; + 64 A6 (H)
; + 68 SR of interrupted task -- ColdFire SR area is 32 bits.
; + 72 PC of task High Memory
;********************************************************************************************************
_OSIntCtxSw:
JSR _OSTaskSwHook ; Invoke user defined context switch hook
MOVE.L (_OSTCBHighRdy),A1 ; OSTCBCur = OSTCBHighRdy
MOVE.L A1,(_OSTCBCur)
MOVE.L (A1),A7 ; CPU stack pointer = OSTCBHighRdy->OSTCBStkPtr
MOVE.B (_OSPrioHighRdy),D0 ; OSPrioCur = OSPrioHighRdy
MOVE.B D0,(_OSPrioCur)
MOVEM.L (A7),D0-D7/A0-A6 ; Pop all the CPU registers from the new task's stack
LEA 60(A7),A7
RTE ; Run task
;*******************************************************************************************************
;
;
;*******************************************************************************************************
_OSIntExitCF:
MOVE SR, D0
ORI.L #$0700,D0 ; Disable interrupts
MOVE D0, SR
MOVE.B (_OSIntNesting),D0
SUBQ.L #1,D0 ; OSIntNesting--
MOVE.B D0,(_OSIntNesting) ; if (OSIntNesting == 0)
TST.B _OSIntNesting
BNE OSIntExitCF_Exit
TST.B _OSLockNesting ; if (OSLockNesting == 0)
BNE OSIntExitCF_Exit
MOVEQ.L #0,D0 ; y = OSUnMapTbl[OSRdyGrp]
MOVE.B _OSRdyGrp,D0
LEA _OSUnMapTbl,A0
MOVE.B (A0,D0.L),D3 ; y is in D3
MOVEQ.L #0,D0 ;
MOVE.B D3,D0 ; copy y into D0
LEA _OSRdyTbl,A0 ;
MOVEQ.L #0,D1 ;
MOVE.B (A0,D0.L),D1 ; D1 = OSRdyTbl[y]
LEA _OSUnMapTbl,A0 ; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]])
MOVE.B D3,D0
LSL.L #3,D0 ; D0 = (y << 3)
MOVE.B (A0,D1.L),D1 ; D1 = OSUnMapTbl[OSRdyTbl[y]]
ADD.L D1,D0 ;
MOVE.B D0,_OSPrioHighRdy ;
MOVE.B _OSPrioHighRdy,D0
MOVE.B _OSPrioCur,D1
ANDI.L #0xFF,D1
ANDI.L #0xFF,D0
CMP.L D1,D0 ; if (OSPrioHighRdy != OSPrioCur) {
BEQ OSIntExitCF_Exit
MOVEQ.L #0,D0 ; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
MOVE.B _OSPrioHighRdy,D0
LEA _OSTCBPrioTbl,A0
MOVEA.L (A0,D0.L*4),A0
MOVE.L A0,_OSTCBHighRdy
ADDQ.L #1,_OSCtxSwCtr ; OSCtxSwCtr++;
; PERFORM INTERRUPT LEVEL CONTEXT SWITCH:
JSR _OSTaskSwHook ; Invoke user defined context switch hook
MOVE.L (_OSTCBHighRdy),A1 ; OSTCBCur = OSTCBHighRdy
MOVE.L A1,(_OSTCBCur)
MOVE.L (A1),A7 ; CPU stack pointer = OSTCBHighRdy->OSTCBStkPtr
MOVE.B (_OSPrioHighRdy),D0 ; OSPrioCur = OSPrioHighRdy
MOVE.B D0,(_OSPrioCur)
OSIntExitCF_Exit:
MOVEM.L (A7),D0-D7/A0-A6 ; Restore processor registers from stack
LEA 60(A7),A7
RTE ; Return to task or nested ISR
;********************************************************************************
; SYSTEM TICK ISR
;
; Description : This function is the ISR used to notify uC/OS-II that a system tick has occurred.
;
; Arguments : none
;
; Notes : 1) You MUST increment 'OSIntNesting' and NOT call OSIntEnter()
; 2) You MUST save ALL the CPU registers as shown below
; 3) You MUST JUMP to OSIntExitCF() instead of call the function.
; 4) You MUST NOT use OSIntExit() to exit an ISR with the 68K.
;
; Procedure : OSTickISR
;
; The procedure is installed as the timer tick ISR and called
; each time TIMER0 on the MCF5282 reaches it's reference value.
;
; Notice that all ISRs *must* leave the same stack context
; at the time of the call to OSIntExit() since if a context
; switch does occur, OSIntCtxSw() must be able to find this
; frame.
;*********************************************************************
_OSTickISR:
LEA -60(A7),A7 ; Save processor registers onto stack
MOVEM.L D0-D7/A0-A6,(A7)
MOVEQ.L #0,D0 ; This use of D0 is absolutely necessary when
MOVE.B (_OSIntNesting),D0 ; using an optimizing compiler. Since ColdFire
ADDQ.L #1,D0 ; can only add Long, whereas OSIntNesting is defined
MOVE.B D0,(_OSIntNesting) ; as INT8U in C code.
CMPI.L #1, d0 ; if OSIntNesting == 1, then continue
BNE _SkipSave ; if Timer interrupts while in another ISR, skip the save
MOVE.L (_OSTCBCur), A1 ; Otherwise, save stack pointer onto current task's stack
MOVE.L A7,(A1)
_SkipSave:
MOVEA.L #_PIT0_PCSR,A0 ; Clear the reference event
MOVE.W (A0),D0 ; Again a point of note, since ORI only works with
ORI.L #_PIF,D0 ; data registers you must do the copy unlike 68k which
MOVE.W D0,(A0) ; has more assembly language options.
JSR _OSTimeTick
; JSR _OSIntExit ; Can either jump to C IntExit or use assembly
JMP _OSIntExitCF ; language, either method seems to work
MOVEM.L (A7),D0-D7/A0-A6 ; Restore processor registers from stack after JSR
LEA 60(A7),A7 ; If using JMP to IntExitCF, these commands are
RTE ; skipped and the restore is at the end of IntExitCF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -