基于ARM920T的OSIntCtxSw()实现分析:
首先必须了解,在将ucos-II移植到ARM920T时,使用了如下结构的任务栈:
程序清单:基于ARM920T的OSIntCtxSw()实现分析:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
|
_IntCtxSw
; OSIntCtxSwFlag = 0
mov r1,#0 str r1,[r0]
/*
此时正处于中断模式下,因此sp、spsr等寄存器为中断模式下的相应寄存器,因此
r0-r3,r12,lr这些寄存器在进入中断处理程序后,先被保存在了中断模式下的堆栈中。*/
;现将这些寄存器的值重新恢复。
ldmfd sp!,{r0-r3,r12,lr} ;将r0-r3重新保存回中断模式下的栈空间
stmfd sp!,{r0-r3} /* 此时中断栈的内容(为被中断任务的r0-r3的值): ----------------à r3,r2,r1,r0
----------------à栈顶 */
;保存中断模式下的栈顶指针sp到r1:r1 = sp_irq
mov r1,sp
add sp,sp,#16; sp_irq += 16; ;计算被中断任务的中断返回地址: r2 = lr – 4
sub r2,lr,#4 /*
spsr在中断发生时,保存了中断前即用户模式下的cpsr的值,该过程由硬件自动完成
*/
;取中断前的状态寄存器到r3
mrs r3,spsr
orr r0,r3,#NOINT;屏蔽中断 ;返回用户模式(切换到用户堆栈),以便下面保存中断现场
msr cpsr_cxsf,r0
;ldr r0,=.+8 ;movs pc,r0;自动切换到用户堆栈 /*
此时已是用户模式,因此,sp为用户模式的栈顶指针,即被中断任务的堆栈指针。
*/
;根据任务栈结构,分别压栈,保存旧任务的现场
stmfd sp!,{r2} ; push old task's pc stmfd sp!,{r4-r12,lr} ; push old task's lr,r12-r4 /* 此时任务栈的内容: ----------------à pc,lr,r12,r11,,,,,,r4
----------------à栈顶 */ ;r1为中断栈的栈顶指针,r4 = r1
mov r4,r1 ; Special optimised code below ;r3为中断前状态寄存器cpsr,r5 = r3
mov r5,r3 ;将保存在中断栈中的r0-r3保存到任务栈中,r4为中断栈的栈顶指针 ldmfd r4!,{r0-r3} stmfd sp!,{r0-r3} ; push old task's r3-r0 ;保存任务的cpsr到任务栈
stmfd sp!,{r5} ; push old task's psr ;保存任务的spsr到任务栈
mrs r4,spsr stmfd sp!,{r4} ; push old task's spsr /*
至此,被中断的任务的现场保存完毕!
*/
; OSPrioCur = OSPrioHighRdy
ldr r4,=OSPrioCur ldr r5,=OSPrioHighRdy ldrb r5,[r5] strb r5,[r4]
; Get current task TCB address:r5= OSTCBCur
ldr r4,=OSTCBCur ldr r5,[r4] ;OSTCBCur->OSTCBStkPtr = SP;
str sp,[r5] ; store sp in preempted tasks's TCB
bl OSTaskSwHook ; call Task Switch Hook
; Get highest priority task TCB address:r6= OSTCBHighRdy
ldr r6,=OSTCBHighRdy ldr r6,[r6] ;SP = OSTCBHighRdy ->OSTCBStkPtr;
ldr sp,[r6] ; get new task's stack pointer
; OSTCBCur = OSTCBHighRdy
str r6,[r4] ; set new current task TCB address
;根据任务栈结构,分别出栈,恢复新任务的现场
ldmfd sp!,{r4} ; pop new task's spsr 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 |