📄 os_cpu_a.s
字号:
/*
; uC/OS-II Porting for LPC210x
; Compiler: gcc
; By Pary WU <parywu@mail2000.com.tw>
;
; History:
; 040627132535:parywu
; The first stable porting, Thumb mode 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
*/
.global OSStartHighRdy
.global OSCtxSw
.global OSIntCtxSw
.global OSGetSR
.global OSPutSR
.global frame_init
.global frame_swi_handler
/* modes, with NOINT */
MODE_NOINT_USR = 0xd0
MODE_NOINT_FIQ = 0xd1
MODE_NOINT_IRQ = 0xd2
MODE_NOINT_SVC = 0xd3
MODE_NOINT_ABT = 0xd7
MODE_NOINT_UND = 0xdb
MODE_NOINT_SYS = 0xdf
MODE_THUMB_BIT = 0x20
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 lbl61
mov r1, #0 /* reset frame_irq_flag to 0 */
str r1, [r0]
b realOSIntCtxSw
lbl61:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -