Hello All,
I am working into a project with automotive microncontroller MPC5604B. I have all the software of a scheduler preentive base and I based in Handler_ISR to know how to the context switch, but i dont know how to perform the context swich or which other handlers I need to use. Is there any example code about how to do this becuase EABI is not completly clear,
thanks.
已解决! 转到解答。
Dear Alonso Vallejo,
Your
requirement is very similar to context switching which is done when interrupt
handler is executed, you can also use the same sequence.
Saving context:
stwu r1, -0x50 (r1) /* Create stack frame */
stw r0, 0x24 (r1) /* Store r0 working register */
/* Save SRR0 and SRR1 */
mfsrr1 r0 /* Store SRR1 (must be done before enabling EE) */
stw r0, 0x10 (r1)
mfsrr0 r0 /* Store SRR0 (must be done before enabling EE) */
stw r0, 0x0C (r1)
/* Clear request to processor; r3 contains the address of the ISR */
stw r3, 0x28 (r1) /* Store r3 */
lis r3, INTC_IACKR@h /* Read pointer into ISR Vector Table & store in r3 */
ori r3, r3, INTC_IACKR@l
lwz r3, 0x0(r3) /* Load INTC_IACKR, which clears request to processor */
lwz r3, 0x0(r3) /* Read ISR address from ISR Vector Table using pointer */
/* Enable processor recognition of interrupts */
wrteei 1 /* Set MSR[EE]=1 */
/* Save rest of context required by EABI */
stw r12, 0x4C (r1) /* Store r12 */
stw r11, 0x48 (r1) /* Store r11 */
stw r10, 0x44 (r1) /* Store r10 */
stw r9, 0x40 (r1) /* Store r9 */
stw r8, 0x3C (r1) /* Store r8 */
stw r7, 0x38 (r1) /* Store r7 */
stw r6, 0x34 (r1) /* Store r6 */
stw r5, 0x30 (r1) /* Store r5 */
stw r4, 0x2C (r1) /* Store r4 */
mfcr r0 /* Store CR */
stw r0, 0x20 (r1)
mfxer r0 /* Store XER */
stw r0, 0x1C (r1)
mfctr r0 /* Store CTR */
stw r0, 0x18 (r1)
mflr r0 /* Store LR */
stw r0, 0x14 (r1)
Restoring context:
/* Restore context required by EABI (except working registers) */
lwz r0, 0x14 (r1) /* Restore LR */
mtlr r0
lwz r0, 0x18 (r1) /* Restore CTR */
mtctr r0
lwz r0, 0x1C (r1) /* Restore XER */
mtxer r0
lwz r0, 0x20 (r1) /* Restore CR */
mtcrf 0xff, r0
lwz r5, 0x30 (r1) /* Restore r5 */
lwz r6, 0x34 (r1) /* Restore r6 */
lwz r7, 0x38 (r1) /* Restore r7 */
lwz r8, 0x3C (r1) /* Restore r8 */
lwz r9, 0x40 (r1) /* Restore r9 */
lwz r10, 0x44 (r1) /* Restore r10 */
lwz r11, 0x48 (r1) /* Restore r11 */
lwz r12, 0x4C (r1) /* Restore r12 */
/* Disable processor recognition of interrupts */
wrteei 0
/* Ensure interrupt flag has finished clearing */
mbar 0
/* Write 0 to INTC_EOIR, informing INTC to lower priority */
li r3, 0
lis r4, INTC_EOIR@h /* Load upper half of INTC_EOIR address to r4 */
ori r4, r4, INTC_EOIR@l
stw r3, 0(r4) /* Write 0 to INTC_EOIR */
/* Restore Working Registers */
lwz r3, 0x28 (r1) /* Restore r3 */
lwz r4, 0x2C (r1) /* Restore r4 */
/* Retrieve SRR0 and SRR1 */
lwz r0, 0x0C (r1) /* Restore SRR0 */
mtsrr0 r0
lwz r0, 0x10 (r1) /* Restore SRR1 */
mtsrr1 r0
/* Restore Other Working Registers */
lwz r0, 0x24 (r1) /* Restore r0 */
/* Restore space on stack */
addi r1, r1, 0x50
Please remember, this is only example code which can need some changes in your project, but from my point of view, this is good base for your development.
Regards,
Martin
Dear Alonso Vallejo,
Your
requirement is very similar to context switching which is done when interrupt
handler is executed, you can also use the same sequence.
Saving context:
stwu r1, -0x50 (r1) /* Create stack frame */
stw r0, 0x24 (r1) /* Store r0 working register */
/* Save SRR0 and SRR1 */
mfsrr1 r0 /* Store SRR1 (must be done before enabling EE) */
stw r0, 0x10 (r1)
mfsrr0 r0 /* Store SRR0 (must be done before enabling EE) */
stw r0, 0x0C (r1)
/* Clear request to processor; r3 contains the address of the ISR */
stw r3, 0x28 (r1) /* Store r3 */
lis r3, INTC_IACKR@h /* Read pointer into ISR Vector Table & store in r3 */
ori r3, r3, INTC_IACKR@l
lwz r3, 0x0(r3) /* Load INTC_IACKR, which clears request to processor */
lwz r3, 0x0(r3) /* Read ISR address from ISR Vector Table using pointer */
/* Enable processor recognition of interrupts */
wrteei 1 /* Set MSR[EE]=1 */
/* Save rest of context required by EABI */
stw r12, 0x4C (r1) /* Store r12 */
stw r11, 0x48 (r1) /* Store r11 */
stw r10, 0x44 (r1) /* Store r10 */
stw r9, 0x40 (r1) /* Store r9 */
stw r8, 0x3C (r1) /* Store r8 */
stw r7, 0x38 (r1) /* Store r7 */
stw r6, 0x34 (r1) /* Store r6 */
stw r5, 0x30 (r1) /* Store r5 */
stw r4, 0x2C (r1) /* Store r4 */
mfcr r0 /* Store CR */
stw r0, 0x20 (r1)
mfxer r0 /* Store XER */
stw r0, 0x1C (r1)
mfctr r0 /* Store CTR */
stw r0, 0x18 (r1)
mflr r0 /* Store LR */
stw r0, 0x14 (r1)
Restoring context:
/* Restore context required by EABI (except working registers) */
lwz r0, 0x14 (r1) /* Restore LR */
mtlr r0
lwz r0, 0x18 (r1) /* Restore CTR */
mtctr r0
lwz r0, 0x1C (r1) /* Restore XER */
mtxer r0
lwz r0, 0x20 (r1) /* Restore CR */
mtcrf 0xff, r0
lwz r5, 0x30 (r1) /* Restore r5 */
lwz r6, 0x34 (r1) /* Restore r6 */
lwz r7, 0x38 (r1) /* Restore r7 */
lwz r8, 0x3C (r1) /* Restore r8 */
lwz r9, 0x40 (r1) /* Restore r9 */
lwz r10, 0x44 (r1) /* Restore r10 */
lwz r11, 0x48 (r1) /* Restore r11 */
lwz r12, 0x4C (r1) /* Restore r12 */
/* Disable processor recognition of interrupts */
wrteei 0
/* Ensure interrupt flag has finished clearing */
mbar 0
/* Write 0 to INTC_EOIR, informing INTC to lower priority */
li r3, 0
lis r4, INTC_EOIR@h /* Load upper half of INTC_EOIR address to r4 */
ori r4, r4, INTC_EOIR@l
stw r3, 0(r4) /* Write 0 to INTC_EOIR */
/* Restore Working Registers */
lwz r3, 0x28 (r1) /* Restore r3 */
lwz r4, 0x2C (r1) /* Restore r4 */
/* Retrieve SRR0 and SRR1 */
lwz r0, 0x0C (r1) /* Restore SRR0 */
mtsrr0 r0
lwz r0, 0x10 (r1) /* Restore SRR1 */
mtsrr1 r0
/* Restore Other Working Registers */
lwz r0, 0x24 (r1) /* Restore r0 */
/* Restore space on stack */
addi r1, r1, 0x50
Please remember, this is only example code which can need some changes in your project, but from my point of view, this is good base for your development.
Regards,
Martin