2013-05-03 29 views
1
.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會去執行任務1碼或1任務執行task0代碼,我不知道爲什麼,需要任何幫助!任務切換沒有成功

+0

代碼對我來說看起來不錯,但這一切都取決於'current_p'中存儲的內容,所以我會在那裏看看。 – ams 2013-05-03 12:57:46

+0

你有一個全局'current_p'並使用'ldr sp,= KERNEL_STACK',所以代碼不可重入。更正常的方法是在上下文切換時切換SVC堆棧。然後'sp_svc&0xfffffc00'可以用來得到一個* current_p *。也就是說,管理員堆棧在每個進程中是獨立的,並且它也可以保存任務恢復信息。對於標準ARM MMU頁面大小,* stack * plus任務結構保持在4k;如果您在沒有MMU的情況下運行,則可以使用任何大小。您還有小頁面,多頁面等。您可以使用'sp_irq'作爲臨時寄存器。在所有條目異常情況下切換到'svc'模式。 – 2013-05-03 13:21:44

+0

+1我看到有人投票。但是,至少您標記了一個實際上是ARM代碼的ARM問題。我想有人希望多一點工作來說出你有沒有做過的事情。你應該看看[entry-armv.S](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/kernel/entry-armv.S)和/或許多其他*開源*項目來獲得一些想法。 ** ARM參考手冊中的Ch 9.6.5上下文切換**也可能有所幫助。絕對用常量重新加載堆棧會破壞堆棧的用途。最終你有多個例外需要幾個幀。 – 2013-05-03 13:31:45

回答

1

現在我的代碼仍然可以保存在IRQ模式下的lr_usr(還原時還原usr_ lr)。我之前發佈的代碼在任務調用某些func時不起作用,如果func被func中斷完成了,並且時鐘中斷改變了current_p,LR在中斷返回後不是正確的lr