任务切换没有成功

时间:2013-05-03 10:48:13

标签: arm task-switching

.macro      SAVE_CONTEXT      SWI_F
    ldr     sp,=current_p               /* switch to pcb */
    ldr     sp,[sp]                     /* get pcb ptr */
    add     sp,sp,#68                   /* point to top of stack */
.if (\SWI_F == 0)                       /* if it is not swi macro */
    sub     lr,lr,#0x04                 /* return addr */
.endif                                  /* lr -= 4 if not swi */
    stmdb   sp!,{lr}
    stmdb   sp!,{r0-r12,lr}             /* prepare to return */ 
    mrs     r1,spsr                     /* r1 <- spsr_usr */
    mrs     r2,cpsr                     /* r2 <- cpsr */
    push    {r1}                        /* save spsr_usr */
    msr     cpsr_c,#SYS_MODE|NO_INTR    /* switch to sys mode */
    mov     r3,sp                       /* r3 <- sp_usr */
    msr     cpsr,r2                     /* switch back */
    push    {r3}                        /* save sp_usr */
    mov     r0,lr                       /* r0 <-- lr */
    msr     cpsr_c,#SVC_MODE|NO_INTR    /* switch back to SVC mode */
    ldr     sp,=KERNEL_STACK            /* switch to SVC stack */
.endm

.macro      SET_ISR_PROC     ISR_PROC   /* */
    ldr     lr,=__restart               /* set return address */
    ldr     pc,=\ISR_PROC               /* call ISR */
.endm

__restart:                              /* restore context */
    ldr     sp,=current_p               /* get pcb */
    ldr     sp,[sp]                     /* adjust back to pcb */
re_restart:                             /* ret from kernel */
    pop     {r3}                        /* r3 <- sp_usr */
    mrs     r2,cpsr                     /* r2 <- cpsr */
    msr     cpsr_c,SYS_MODE|NO_INTR     /* switch to sys mode*/
    mov     sp,r3                       /* sp_usr <-- r3 */
    msr     cpsr,r2                     /* switch back */
    pop     {r1}                        /* r1 <- spsr_usr */
    msr     spsr,r1                     /* restore spsr */
    ldmia   sp!,{r0-r12,lr,pc}^         /* intr ret */

_do_irq:
    SAVE_CONTEXT    0                   /* not swi */
    SET_ISR_PROC    do_irq

这个任务切换代码在我的s3c2440板上运行良好,当我只有一个任务但是当创建了两个或更多任务时,task0将执行task1代码或任务1执行task0代码,我不知道为什么,需要任何帮助!

1 个答案:

答案 0 :(得分:1)

现在代码还可以。我在IRQ模式下保存了lr_usr(当返回时也恢复了usr_ lr)。我发布的代码在任务调用某些函数时将无效,如果func被func中断而未完成然而,时钟中断改变了current_p,中断返回后LR不是正确的lr