Переключение задач не сработало
.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, когда я получил только одну задачу, но когда две или более задач созданы, задача 0 перейдет к выполнению кода задачи 1 или задача 1 выполнит код задачи 0, я не знаю почему, любая помощь необходимость!
1 ответ
Решение
Теперь код в порядке, теперь я сохранил lr_usr в режиме IRQ (восстановите usr_ lr и при возврате). Код, который я выложил ранее, не сработает, когда задача вызовет какой-нибудь функционал, если он прерывается, а функция еще не завершена, и изменение тактового прерывания current_p, LR не является правильным lr после возврата прерывания