arm - task switching didn't work out -
.macro save_context swi_f ldr sp,=current_p /* switch pcb */ ldr sp,[sp] /* pcb ptr */ add sp,sp,#68 /* point top of stack */ .if (\swi_f == 0) /* if not swi macro */ sub lr,lr,#0x04 /* return addr */ .endif /* lr -= 4 if not swi */ stmdb sp!,{lr} stmdb sp!,{r0-r12,lr} /* prepare 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 sys mode */ mov r3,sp /* r3 <- sp_usr */ msr cpsr,r2 /* switch */ push {r3} /* save sp_usr */ mov r0,lr /* r0 <-- lr */ msr cpsr_c,#svc_mode|no_intr /* switch svc mode */ ldr sp,=kernel_stack /* switch 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 /* pcb */ ldr sp,[sp] /* adjust pcb */ re_restart: /* ret kernel */ pop {r3} /* r3 <- sp_usr */ mrs r2,cpsr /* r2 <- cpsr */ msr cpsr_c,sys_mode|no_intr /* switch sys mode*/ mov sp,r3 /* sp_usr <-- r3 */ msr cpsr,r2 /* switch */ 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 this task switching code works on s3c2440 board when got 1 task when 2 or more tasks created ,task0 go execute task1 code or task 1 execute task0 code ,i do't know why ,any need !
the code ok atfer saved lr_usr @ irq mode (restore usr_ lr when return also).the code posted before not work out when task call func ,if func interrupted func not finished yet ,and clock interrupt change current_p,the lr not right lr after interrupt return
Comments
Post a Comment