Hi there,
While I have been working with embedded systems for long enough, I don’t have much experience with ARM and have a situation where I have to write/modify some assembly code. Part of this involves some critical sections and my current method of doing this has just been to rely on the CPSID and CPSIE instructions to mask off all maskable interrupts during my critical section.
This works fine, but doing some reading online I have found some code examples that appear to add the extra step of saving the mask register, then disabling interrupts, then restoring the mask register which has the advantage of allowing some interrupts to be selectively masked both before and after the critical section. In comparison the use of CPSID disables everything and CPSIE enables everything regardless of whether it was enabled prior or not.
My major concern is that saving the register and restoring it after looks like it introduces a read-modify-write sequence that is not fully atomic - I am hoping that someone here can point out to me how this sequence of instructions is considered safe. I am hoping it is a feature of the architecture I am not familiar with, but want to learn about.
Example from an article about how to do critical sections ‘properly’ here http://mcuoneclipse.com/2014/01/26/ente … ing-badly/
asm ( \
"MRS R0, PRIMASK\n\t" \
"CPSID I\n\t" \
I guess my question boils down to wondering what prevents an ISR which would modify PRIMASK from firing just before/just after the read of PRIMASK here (which results in a Read-Modify-Write error that would overwrite that modification). Does the MRS instruction implicitly delay the onset of any interrupts for 2+ cycles?
Thanks in advance and hoping that the world isn’t full of dangerously unstable ARM code