I had a code like below to make some Flgas set/clear;
unsigned short FlagReg; int main(void) { ... FlagReg = FlagReg | 0x0001; // makes first bit TRUE ... } void Timer1Handler(void) _irq { ... FlagReg = FlagReg & 0xFFFD; // makes second bit FALSE ... }
This code seems to work. It works correct normally but it doesn't sometimes. It's because making second bit at timer1 interrupt doesn't work.
So, I thought of its assembly. It's like below:
main: LDR R0,[PC,#xxxx] LDR R0,[R0,#xxxx] ORR R0,R0,0x0001 -> interrupt may occur at this line LDR R1,[PC,#xxxx] LDR R0,[R1,#xxxx]
If timer interrupt occurs at shown line what will happens? I think, makeing clear second bit will be not valid. Second bit was made clear and register was changed at timer0 interrupt but the value to write into register has been alerady calculated at previous line.
I hope that I could explain the problem. What can I do to solve this problem?
Best regards.
You have several options.
1) Some Cortex-M processors have the bit-banding feature. It allows you to flip bits atomically. Look it up. This is the easiest option.
2) You can disable interrupts (or just one interrupt) for the duration of flag modification in main(). Not very nice for a number of reasons.
3) You can design your logic in such a way that you don't need to modify the same variable both in main() and the interrupt handler. This way is portable since it does not rely on special CPU features like bit-banding, and it does not need disable interrupts.