📄 os_cpu_a.s
字号:
;------------------------------------------------------------------------------
;- ATMEL Microcontroller Software Support - ROUSSET -
;------------------------------------------------------------------------------
; The software is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;-----------------------------------------------------------------------------
;- File source : os_cpu.s
;- Object : AT91 Ucos specific assembly functions
;-
;- 1.0 21/08/00 EL : creation
;------------------------------------------------------------------------------
AREA |subr|, CODE, READONLY, INTERWORK
INCLUDE targets/eb40/eb40.inc
INCLUDE macros.inc
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSRunning
IMPORT OSIntNesting
IMPORT OSTimeTick
IMPORT OSIntEnter
IMPORT OSIntExit
; IMPORT TmrMaintain
IMPORT ARMIntNesting
EXPORT OSTickISR
EXPORT OSIntCtxSw
EXPORT __OS_TASK_SW
EXPORT __OSStartHighRdy
;--------------------------------------------------------------------------------------
OSIntCtxSw
; Interrupt Exit if higher priority task ready to run
; New Task Context switch
add sp,sp, #8; ; adjust sp to compensate for the call to OSIntExit
; ldr r12, =AIC_BASE
; str r12, [r12, #AIC_EOICR] ; write any value to EOICR to signal end of int
;---------------------------------------------------------
;If current interrupt entered from another low priority interrupt, no switch
;mrs r1,SPSR
;and r11,r1,#0x1F ; mask out all but the mode bits
;teq r11,#ARM_MODE_IRQ ; check for interrupted IRQ thread
; if EQ then we can return immediately
;bne OSIntCtxSw_1
;msreq SPSR_cxsf,r1 ; restore the SPSR
;addeq sp,sp,#4
;ldmeqfd sp!,{r0-r12,r14,pc}^ ; and return to the interrupted thread
OSIntCtxSw_1
;OSPrioCur = OSPrioHighRdy
ldr r4, =OSPrioCur ; load the current priority pointer
ldr r5, =OSPrioHighRdy ; load address of highest prio task
ldrb r6, [r5] ; load value of highest prio task
strb r6, [r4] ; store value of highest in current
; Get current task TCB address
ldr r4, =OSTCBCur ; load pointer
ldr r5, [r4] ; load current tcb sp
str sp, [r5] ; store sp in preempted tasks's TCB
; Get highest priority task TCB address
ldr r6, =OSTCBHighRdy
ldr r6, [r6] ; get highrdy's sp
ldr sp, [r6] ; set sp = highrdy[sp]
; OSTCBCur = OSTCBHighRdy
str r6, [r4] ; set new current task TCB address
ldr r12, =AIC_BASE
str r12, [r12, #AIC_EOICR] ; write any value to EOICR to signal end of int
;
ldmfd sp!, {r4} ; load saved cpsr from stack
msr CPSR_cxsf, r4 ; cpsr = saved cpsr
ldmfd sp!, {r0-r12, r14,pc} ; restore r0-r12 and lr interworking
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
__OS_TASK_SW
; Call from SWI interrupt
; New Task Context switch
msr CPSR_c,#I_BIT :OR: ARM_MODE_SYS ;enter SYS mode and save registers
stmfd sp!, {r0-r12,r14,pc}
msr CPSR_c,#I_BIT :OR: ARM_MODE_SVC ;return to SVC mode to get SPSR and R14
mov r12, r14
mrs r4, SPSR
msr CPSR_c,#I_BIT :OR: ARM_MODE_SYS ;go back to SYS mode
add sp,sp,#15*4
stmfd sp!, {r12} ;save r12(actually, r14 and pc when return)
sub sp,sp,#14*4
stmfd sp!, {r4} ;save SPSR to stack
;--------------------------------------------------------------------------------------
OSCtxSw
;OSPrioCur = OSPrioHighRdy
ldr r4, =OSPrioCur ; load the current priority pointer
ldr r5, =OSPrioHighRdy ; load address of highest prio task
ldrb r6, [r5] ; load value of highest prio task
strb r6, [r4] ; store value of highest in current
; Get current task TCB address
ldr r4, =OSTCBCur ; load pointer
ldr r5, [r4] ; load current tcb sp
str sp, [r5] ; store sp in preempted tasks's TCB
; Get highest priority task TCB address
ldr r6, =OSTCBHighRdy
ldr r6, [r6] ; get highrdy's sp
ldr sp, [r6] ; set sp = highrdy[sp]
; OSTCBCur = OSTCBHighRdy
str r6, [r4] ; set new current task TCB address
ldmfd sp!, {r4} ; load saved cpsr from stack
msr CPSR_cxsf, r4 ; cpsr = saved cpsr
ldmfd sp!, {r0-r12, r14,pc} ; restore r0-r12 and lr interworking
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
;This function is called from SWI and after reaching here, the mode has been SYSTEM
__OSStartHighRdy
; Set OSRunning == TRUE
ldr r4, =OSRunning ;point r4 to OSRunning
mov r5, #1 ;move 1 into r5
strb r5, [r4] ;store r5 in [r4]
; Get current task TCB address
ldr r4, =OSTCBCur ;point to current tcb
; Get highest priority task TCB address
ldr r5, =OSTCBHighRdy ;point to highest tcb
ldr r5, [r5] ; get stack pointer
ldr sp, [r5] ; sp = highrdy[sp]
str r5, [r4] ; set current tcb = highrdy tcb
ldmfd sp!, {r4} ; get cpsr new state from top of the stack
msr CPSR_cxsf, r4 ; set cpsr = saved CPSR
ldmfd sp!, {r0-r12, r14,pc} ; restore registers r0-r12 and lr
;--------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------
OSTickISR
ENTER_INTERRUPT
;read the interrupt status reg to clear it
;
ldr r12,=TC0_BASE ; load tc0 base address
ldr r12,[r12, #0x020] ; read from status register offse
;
ldr r12, =OSTimeTick
mov r14,pc
bx r12 ; Branch to OsTimeTick
; ldr r12, =TmrMaintain
;mov r14,pc
;bx r12 ; Branch to OsTimeTick
; Interrupt Exit if no higher priority task ready to run
; restore interrupted task
EXIT_INTERRUPT
;--------------------------------------------------------------------------------------
END
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -