📄 os_cpu_a.s
字号:
;**********************************************************************
;****************************************************
; $Workfile: os_cpu_a.S for SkyEye simulator $
; $Revision: 1.1.1.1 $
; $Author: skyeye $
; $Email: lmcs00;mails.tsinghua.edu.cn $
; $Date: 2003/02/19 02:42:22 $
;****************************************************
;****************************************************
; $Workfile: os_cpu_a.S for SkyEye simulator $
; $Revision: 1.1.1.1 $
; $Author: skyeye $
; $Email: chenyu;hpclab.cs.tsinghua.edu.cn $
; $Email: lmcs00;mails.tsinghua.edu.cn $
; $Date: 2003/02/19 02:42:22 $
;****************************************************
;****************************************************
; $Workfile: os_cpu_a.S for SkyEye simulator $
; $Revision: 1.1.1.1 $
; $Author: skyeye $
; $Email: chenyu;hpclab.cs.tsinghua.edu.cn $
; $Email: lmcs00;mails.tsinghua.edu.cn $
; $Date: 2003/02/19 02:42:22 $
;****************************************************
; BASED ON
;***************************************************
; $Workfile: Os_cpu_a.s $
; $Revision: 1.1.1.1 $
; $Author: skyeye $
; $Date: 2003/02/19 02:42:22 $
; **************************************************
;********************************************************************/
AREA |subr|, CODE, READONLY
;/***********************************************************************
;
; Function: OSStartHighRdy
;
; Purpose:
; To start the task with the highest priority during OS startup
;
; Processing:
; See uC/OS-II Task Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; Called once during OSStart()
;
;*********************************************************************/
EXPORT OSStartHighRdy
IMPORT OSTaskSwHook
IMPORT OSTCBHighRdy
IMPORT OSTCBCur
IMPORT OSRunning
OSStartHighRdy
MSR CPSR_cxsf,#0xD3 ; Switch to SVC mode with IRQ and FIQ disabled
BL OSTaskSwHook ; Call user-defined hook function
LDR r4,=OSRunning ; Indicate that multitasking has started
MOV r5, #1
STRB r5, [r4] ; OSRunning = true
LDR r5, =OSTCBCur
LDR r4, =OSTCBHighRdy ; Get highest priority task TCB address
LDR r4, [r4] ; get stack pointer
LDR sp, [r4] ; switch to the new stack
STR r4, [r5]
; next two lines removed by YJ
LDMFD sp!, {r4} ; pop new task s spsr_cxsf
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task s psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task s r0-r12,lr & pc
;/***********************************************************************
;
; Function: OS_TASK_SW
;
; Purpose:
; To perform a context switch from the Task Level.
;
; Processing:
; See uC/OS-II Task Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; The whole function is executed in CRITICAL state. See OSSched().
;
; On entry, OSTCBCur and OSPrioCur hold the current TCB and priority
; and OSTCBHighRdy and OSPrioHighRdy contain the same for the task
; to be switched to.
;
; The following code assumes that the virtual memory is directly
; mapped into physical memory. If this is not true, the cache must
; be flushed at context switch to avoid address aliasing.
;
;*********************************************************************/
EXPORT OSCtxSw
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
IMPORT OSTaskSwHook
IMPORT OSTCBHighRdy
OSCtxSw
STMFD sp!, {lr} ; push pc (lr is actually be pushed in place of PC)
STMFD sp!, {r0-r12,lr} ; push lr & register file
MRS r4, cpsr
STMFD sp!, {r4} ; push current psr
MRS R4,SPSR
STMFD SP!,{R4} ; push current SPSR
; next two lines removed by YJ
; MRS r4, spsr
; STMFD sp!, {r4} ; push current spsr_cxsf
BL OSTaskSwHook ; call Task Switch Hook
LDR r4, =OSTCBCur ; Get current task TCB address
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks s TCB
; OSIntCtxSw does the remainder work, so
; following removed by YJ-------------------------------------------<<
;_OSCtxSw
LDR R4,=OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5,=OSPrioHighRdy
LDRB R6,[R5]
STRB R6,[R4]
LDR R4,=OSTCBCur ; Get the current task's OS_TCB address
LDR R6,=OSTCBHighRdy ; Get highest priority task's OS_TCB address
LDR R6,[R6]
LDR SP,[R6] ; get new task's stack pointer
STR R6,[R4] ; OSTCBCur = OSTCBHighRdy
;; next two lines removed by YJ
LDMFD sp!, {r4} ; pop new task spsr_cxsf
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task cpsr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task r0-r12,lr & pc
MOV pc, lr ; return
;***********************************************************************
;
; Function: OSIntCtxSw
;
; Purpose:
; To perform a context switch from the interrupt level.
;
; Processing:
; See uC/OS-II Interrupt Level Context Switch flow chart
;
; Parameters: void
;
; Outputs: None
;
; Returns: void
;
; Notes:
; Sets up the stacks and registers to call the task level
; context switch
;
;*********************************************************************/
EXPORT OS_IntCtxSw
;----------------------------------------------------------------
; modefied by YJ
;----------------------------------------------------------------
; added starts --------------<<
IMPORT OSTaskSwHook
IMPORT OSIntCtxSwFlag
OS_IntCtxSw
LDR R0,=OSIntCtxSwFlag ; OSIntCtxSwFlag = FALSE
MOV R1,#0
STR R1,[R0]
LDMFD SP!,{R0-R3,R12,LR} ; Clean up IRQ stack
STMFD SP!,{R0-R3} ; We will use R0-R3 as temporary registers
MOV R1,SP
ADD SP,SP,#16
SUB R2,LR,#4
MRS R3,SPSR ; Disable interrupts for when we go back to SVC mode
ORR R0,R3,#0xc0
MSR SPSR_c,R0
LDR R0,=.+8 ; Switch back to SVC mode (Code below, current location + 2 instructions)
MOVS PC,R0 ; Restore PC and CPSR
; SAVE OLD TASK'S CONTEXT ONTO OLD TASK'S STACK
STMFD SP!,{R2} ; Push task's PC
STMFD SP!,{R4-R12,LR} ; Push task's LR,R12-R4
MOV R4,R1 ; Move R0-R3 from IRQ stack to SVC stack
MOV R5,R3
LDMFD R4!,{R0-R3} ; Load R0-R3 from IRQ stack
STMFD SP!,{R0-R3} ; Push R0-R3
STMFD SP!,{R5} ; Push task's CPSR
MRS R4,SPSR
STMFD SP!,{R4} ; Push task's SPSR
LDR R4,=OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP
LDR R5,[R4]
STR SP,[R5]
BL OSTaskSwHook ; call Task Switch Hook
LDR R4,=OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5,=OSPrioHighRdy
LDRB R6,[R5]
STRB R6,[R4]
LDR R4,=OSTCBCur ; OSTCBCur = OSTCBHighRdy
LDR R6,=OSTCBHighRdy
LDR R6,[R6]
LDR SP,[R6]
STR R6,[R4]
LDMFD SP!,{R4} ; pop new task's SPSR
; AND R4,R4,#0xffffFF3F
MSR SPSR_cxsf,R4
LDMFD SP!,{R4} ; pop new task's PSR
; AND R4,R4,#0xffffFF3F
MSR CPSR_cxsf,R4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task r0-r12,lr & pc
; >>---------------- added ends
; removed starts ------------<<
; IMPORT OSIntCtxSwFlag
;OSIntCtxSw
; LDR r0, =OSIntCtxSwFlag ; OSIntCtxSwFlag = true
; MOV r1, #1
; STR r1, [r0]
;
MOV pc, lr ; return
; >>-------------- removed ends
;----------------------------------------------------------------
; end of modification
;----------------------------------------------------------------
;/***********************************************************************
;
;yangye 2003-2-14
;changed this function name from OSTickISR to OSISR(it is not a TICK isr)
; Function: OSISR
;
; Purpose:
; The IRQ interrupt handler
;
; Processing:
; Saves context
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -