`
nathan09
  • 浏览: 145566 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

ucOS-II基于ARM920T的OSIntCtxSw实现分析

 
阅读更多

基于ARM920TOSIntCtxSw()实现分析:

首先必须了解,在将ucos-II移植到ARM920T时,使用了如下结构的任务栈:

程序清单:基于ARM920TOSIntCtxSw()实现分析:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

_IntCtxSw

; OSIntCtxSwFlag = 0

mov r1,#0

str r1,[r0]

/*

此时正处于中断模式下,因此spspsr等寄存器为中断模式下的相应寄存器,因此

r0-r3,r12,lr这些寄存器在进入中断处理程序后,先被保存在了中断模式下的堆栈中。*/

;现将这些寄存器的值重新恢复。

ldmfd sp!,{r0-r3,r12,lr}

;将r0-r3重新保存回中断模式下的栈空间

stmfd sp!,{r0-r3}

/*

此时中断栈的内容(为被中断任务的r0-r3的值)

----------------à

r3,r2,r1,r0

----------------à栈顶

*/

;保存中断模式下的栈顶指针spr1r1 = 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为中断前状态寄存器cpsrr5 = 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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics