📄 os_cpu_a.s
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; uC/OS-II Porting for LPC210x
; Compiler: ADS 1.2
; By Pary WU <parywu@mail2000.com.tw>
;
; History:
; 040627132535:parywu
; The first stable porting, Thumb mod is not considered yet.
; 040628191610:parywu
; ARM/Thumb interworking okay.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IMPORT IRQ_VECTOR_4 ;use timer0 as ticker
IMPORT frame_irq_flag
IMPORT OSTCBHighRdy
IMPORT OSTaskSwHook
IMPORT OSRunning
IMPORT OSTCBCur
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSIntEnter
IMPORT OSTimeTick
IMPORT OSIntExit
EXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw
EXPORT OSGetSR
EXPORT OSPutSR
EXPORT frame_init
EXPORT frame_swi_handler
;; modes, with NOINT
MODE_NOINT_USR EQU 0xd0
MODE_NOINT_FIQ EQU 0xd1
MODE_NOINT_IRQ EQU 0xd2
MODE_NOINT_SVC EQU 0xd3
MODE_NOINT_ABT EQU 0xd7
MODE_NOINT_UND EQU 0xdb
MODE_NOINT_SYS EQU 0xdf
MODE_THUMB_BIT EQU 0x20
CODE32
AREA EXTERNINIT, CODE, READONLY
frame_swi_handler
;not used yet
bx lr
frame_tick_handler
;called under sys mode
ldr r0, =0xe0004000 ;rT0IR
mov r1, #1 ;stop MR0
str r1, [r0]
IMPORT OSIntEnter
IMPORT OSTimeTick
IMPORT OSIntExit
stmfd sp!, {r12, lr}
bl OSIntEnter
bl OSTimeTick
bl OSIntExit
ldmfd sp!, {r12, lr}
;; check flag afterward
;; to avoid calculation of the stack size of OSIntExit
ldr r0, =frame_irq_flag
ldr r1, [r0]
cmp r1, #0
beq %61
mov r1, #0 ;reset frame_irq_flag to 0
str r1, [r0]
b realOSIntCtxSw
61
bx lr
frame_init
ldr r0, =IRQ_VECTOR_4
ldr r1, =frame_tick_handler
str r1, [r0]
bx lr
OSIntCtxSw
ldr r0, =frame_irq_flag
mov r1, #1
str r1, [r0]
bx lr
realOSIntCtxSw
; unwind IRQ's stack
msr cpsr_c, #MODE_NOINT_IRQ
add sp, sp, #4 ;drop
msr cpsr_c, #MODE_NOINT_SYS
b OSCtxSw_2
OSCtxSw
; entered on SYS mode
; CONTEXT in stack
; cpsr
; pc
; lr
; r12
; r11
; r10
; r9
; r8
; r7
; r6
; r5
; r4
; r3
; r2
; r1
; r0 <= sp
stmfd sp!, {r0-r1} ;dummy for cpsr, pc
stmfd sp!, {r0-r12, lr}
mrs r0, cpsr
str r0, [sp, #60]
str lr, [sp, #56]
OSCtxSw_2
; save context to OSTCBCur
ldr r0, =OSTCBCur
ldr r0, [r0]
str sp, [r0, #0]
; OSTCBCur = OSTCBHighRdy
ldr r0, =OSTCBCur
ldr r1, =OSTCBHighRdy
ldr r2, [r1]
str r2, [r0]
; OSPrioCur = OSPrioHighRdy
ldr r0, =OSPrioCur
ldr r1, =OSPrioHighRdy
ldrb r2, [r1]
strb r2, [r0]
; call OSTaskSwHook
bl OSTaskSwHook
; restore context at OSTCBHighRdy
ldr r0, =OSTCBHighRdy
ldr r0, [r0]
ldr sp, [r0, #0]
ldr r0, [sp, #60] ;cpsr
ldr r1, [sp, #56] ;pc
movs r2, r1, lsl #31
orrmi r0, r0, #MODE_THUMB_BIT ;cpsr may be changed between context switches
;but pc won't
;so use return address to identify thumb mode
msr cpsr_c, #MODE_NOINT_SVC
stmfd sp!, {r1}
msr spsr_cf, r0
msr cpsr_c, #MODE_NOINT_SYS
ldmfd sp!, {r0-r12, lr}
add sp, sp, #8 ;drop 2 items (cpsr, pc)
msr cpsr_c, #MODE_NOINT_SVC
ldmfd sp!, {pc}^
OSStartHighRdy
bl OSTaskSwHook
ldr r0, =OSRunning
mov r1, #1
strb r1, [r0, #0]
ldr r0, =OSTCBHighRdy
ldr r0, [r0]
ldr sp, [r0, #0]
ldr r0, [sp, #60] ;cpsr
ldr r1, [sp, #56] ;pc
msr cpsr_c, #MODE_NOINT_SVC
stmfd sp!, {r1}
msr spsr_cf, r0
msr cpsr_c, #MODE_NOINT_SYS
ldmfd sp!, {r0-r12, lr}
add sp, sp, #8 ;drop 2 items (cpsr, pc)
msr cpsr_c, #MODE_NOINT_SVC
ldmfd sp!, {pc}^
OSGetSR
mrs r0, cpsr
orr r1, r0, #0x80
msr cpsr_c, r1
bx lr
OSPutSR
msr cpsr_c, r0
bx lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -