📄 os_cpu_a.s
字号:
;*
;* File: os_cpu_a.s
;*
;* (c) Copyright ARM Limited 1999. All rights reserved.
;*
;* ARM Specific code
;*
;*
;
; Functions defined in this module:
;
; void ARMDisableInt(void) /* disable interrupts when in SVC */
; void ARMEnableInt(void) /* enable interrupts when in SVC */
; void OSCtxSw(void) /* context switch */
; void OSStartHighRdy(void) /* start highest priority task */
NoInt EQU 0x80
BIT_TIMER0 EQU (0x1<<13)
BIT_TIMER3 EQU (0x1<<10)
BIT_TIMER5 EQU (0x1<<8)
BIT_SIO EQU (0x1<<4)
BIT_EINT4567 EQU (0x1<<21)
I_ISPC EQU 0x1e00024
INTMSK EQU 0x1e0000c
EXTINTPND EQU 0x1d20054
AREA |Assembly$$code|, CODE, READONLY
EXPORT TickHandler
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;-------------------------------------------------------
; uC/OS Porting Core Function : ARMDisableInt
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
EXPORT ARMDisableInt
ARMDisableInt
STMDB sp!, {r0}
MRS r0, CPSR
ORR r0, r0, #NoInt
MSR CPSR_cxsf, r0
LDMIA sp!, {r0}
MOV pc, lr
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;-------------------------------------------------------
; uC/OS Porting Core Function : ARMEnableInt
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
EXPORT ARMEnableInt
ARMEnableInt
STMDB sp!, {r0}
MRS r0, CPSR
BIC r0, r0, #NoInt
MSR CPSR_cxsf, r0
LDMIA sp!, {r0}
MOV pc, lr
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;-------------------------------------------------------
; uC/OS Porting Core Function : OSStartHighRdy
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IMPORT OSTaskSwHook
IMPORT OSRunning
IMPORT OSTCBHighRdy
EXPORT OSStartHighRdy
OSStartHighRdy
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSRunning ; Indicate that multitasking has started
MOV r1, #1
STRB r1, [r0]
LDR r0, =OSTCBHighRdy ; r0 <= &OSTCBHighRdy
LDR r0, [r0] ; r0 <= OSTCBHighRdy
LDR sp, [r0] ; sp <= OSTCBHighRdy->OSTCBStkPtr
LDMFD sp!, {r0} ; restore SP...
MSR CPSR_xsf, r0
LDMFD sp!, {r0-r12, lr, pc} ; Load task's context & Run task
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;--------------------------------------------------------
; uC/OS Porting Core Function : OSCtxSw
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IMPORT OSTCBCur
IMPORT OSTaskSwHook
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
EXPORT OSCtxSw
OSCtxSw
STMFD sp!, {lr} ; push resume address
STMFD sp!, {r0-r12, lr} ; push rest context
MRS r0, CPSR
STMFD sp!, {r0} ; push CPSR
LDR r0, =OSTCBCur ; r0 <= &OSTCBCur
LDR r0, [r0] ; r0 <= OSTCBCur
STR sp, [r0] ; OSTCBCur->OSTCBStkPtr = sp
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSTCBCur ; r0 <= &OSTCBCur
LDR r1, =OSTCBHighRdy ; r1 <= &OSTCBHighRdy
LDR r2, [r1] ; r2 <= OSTCBHighRdy
STR r2, [r0] ; OSTCBCur = OSTCBHighRdy
LDR r0, =OSPrioCur ; r0 <= &OSPrioCur
LDR r1, =OSPrioHighRdy ; r1 <= &OSPrioHighRdy
LDRB r3, [r1] ; r3 <= OSPrioHighRdy
STRB r3, [r0] ; OSPrioCur = OSPrioHighRdy
LDR sp, [r2] ; sp <= OSTCBHighRdy->OSTCBStkPtr
LDMFD sp!, {r0} ; restore SP...
MSR CPSR_xsf, r0
LDMFD sp!, {r0-r12, lr , pc} ; Load task's context & Run task
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;--------------------------------------------------------
; uC/OS Porting Core Function : OSIntCtxSw
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IMPORT OSTCBCur
IMPORT OSTaskSwHook
IMPORT OSTCBHighRdy
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
EXPORT OSIntCtxSw
OSIntCtxSw
LDR r0, =SAVED_SVC_SP
LDR r1, [r0]
LDR r0, =OSTCBCur ; r0 <= &OSCTBCur
LDR r0, [r0] ; r0 <= OSCTBCur
STR r1, [r0] ; OSTCBCur->OSTCBStkPtr = sp
BL OSTaskSwHook ; Call user defined task switch hook
LDR r0, =OSTCBCur ; r0 <= &OSTCBCur
LDR r1, =OSTCBHighRdy ; r1 <= &OSTCBHighRdy
LDR r2, [r1] ; r2 <= OSTCBHighRdy
STR r2, [r0] ; OSTCBCur = OSTCBHighRdy
LDR r0, =OSPrioCur ; r0 <= &OSPrioCur
LDR r1, =OSPrioHighRdy ; r1 <= &OSPrioHighRdy
LDRB r3, [r1] ; r3 <= OSPrioHighRdy
STRB r3, [r0] ; OSPrioCur = OSPrioHighRdy
LDR sp, [r2] ; sp <= OSTCBHighRdy->OSTCBStkPtr
;在不打开中断的情况下,进行任务切换
LDMFD sp!, {r0}
MSR CPSR_xsf, r0
LDMFD sp!, {r0-r12, lr, pc} ; * the interrupt is enable after executing this sentence
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;-------------------------------------------------------
; uC/OS Porting Core Function : ExIntHandler4567
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IMPORT OSIntNesting
IMPORT OSTimeTick
IMPORT OSIntExit
IntExit
MSR CPSR_cxsf, r3
LDMFD r2, {r0-r3, pc} ; do not execute the ISR to prevent pumping the stack
EXPORT TickHandler
TickHandler
SUB lr, lr, #4
STMFD sp!, {r0-r3, lr} ; push r0-r3, pc
LDR r0, =I_ISPC
LDR r1, =BIT_TIMER5
STR r1, [r0] ; clear the interrupt pending bit
MOV r1, lr ; r1 <- return pc
MOV r2, sp ; r2 <- sp_irq
ADD sp, sp, #20 ; adjust the sp
;............ Added for the sake of preventing interrupt nesting ................
mrs r3, spsr ; r3 <- spsr_irq
orr r0, r3, #0x80 ; mask the interrupt
msr spsr_cf, r0 ; change spsr_irq
;................................................................................
LDR r0,=IRQ_2
MOVS pc,r0 ; At this point, cpsr_svc := spsr_irq...
IRQ_2
ldr r0, =OSIntNesting
ldrb r0, [r0]
cmp r0, #8
bcs IntExit ; 如果OSIntNesting>8, IntExit
CMP r0, #0
BEQ %F1
0
stmfd sp!, {r1} ; push SVC's pc to task stack
stmfd sp!, {r4-r12,lr} ; push SVC's r14, r12-r4 to task stack
mov r7, r3 ; cpsr
ldmfd r2, {r0-r3} ; pop r0~r3 in irq stack
stmfd sp!, {r0-r3} ; push r0~r3 to task stack
stmfd sp!, {r7} ; push cpsr to task stack
B %F2
1
stmfd sp!, {r1} ; push SVC's pc to task stack
stmfd sp!, {r4-r12,lr} ; push SVC's r14, r12-r4 to task stack
mov r7, r3 ; cpsr
ldmfd r2, {r0-r3} ; pop r0~r3 in irq stack
stmfd sp!, {r0-r3} ; push r0~r3 to task stack
stmfd sp!, {r7} ; push cpsr to task stack
LDR r0, =SAVED_SVC_SP
STR sp, [r0]
LDR r0, =IntReStackTop
MOV sp, r0
2
LDR r0, =OSIntNesting ; Notify uC/OS-II of ISR
LDRB r1, [r0]
ADD r1, r1, #1 ;OSIntNesting++
STRB r1, [r0]
BL OSTimeTick ; Process system tick
BL OSIntExit ; Notify uC/OS-II of end of ISR
LDR r0, =OSIntNesting
LDRB r0, [r0]
CMP r0, #0
BNE %F1
LDR r0, =SAVED_SVC_SP
LDR sp, [r0]
1
LDMFD sp!, {r0}
MSR CPSR_cxsf, r0
LDMFD sp!, {r0-r12, lr, pc} ; restore the context
AREA INT_DATA, DATA, READWRITE
SAVED_SVC_SP DCD 0
IntReStack % 2048
IntReStackTop % 4 ;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -