I'm running a round robin multitasker on a 56F801. Interrupts are heavily used, but not for task switching. When I go to change the stack pointer (SP) I find that I must lock out interrupts around the following: move x:(r3),sp nop move x:(sp)-,r1 move x:(sp)-,r2 move x:(r1)+,b rts where r3 contains the address of a different task's saved stack pointer. r1, r2, and b need to be preserved across task switching (r1 is used as a data stack pointer, r2 must be preserved, and b is the top element of the data stack that r1 points to) Adding a bfset #$200,sr and replacing the rts with an rti (to allow the pulling of the stacked status, therefore restoring the state of the interrupt mask) fixes this. eg: bfset #$200,sr move x:(r3),sp nop move x:(sp)-,r1 move x:(sp)-,r2 move x:(r1)+,b rti Also running the code with interrupts enabled but not occuring also fixes the problem. Only if I change sp with interrupts allowed and occuring does this code fail. I am assuming that the other 3 move instructions are not the problem though. I expect this is a problem with the chip's pipelining. I have not been able to find anything on-line, in the manuals, in the on-line ap notes or errata, or in this group. Any thoughts? What am I missing? Gary |
56f80x interrupt/pipeline problem?
Started by ●October 19, 2004