On a Cortex R, where ldm/stm are interruptible, can i use ldrex and strex for double words to pass from ISR to a task in this way?
in ISR:
STREXD, // Ignoring (yes, dumping it) if it actually failed to write , do no spin-lock or retry here at all
in Task :
LDREXD // load .. CLREX // clear exclusion
One core (2 in dual lock-step), no sharing mem with other cores. Will this work for automically write/read double words in the scenario one ISR feeding a task?
And yes, no buffering between them.
42Bastian Schick So I would need to do a first 'wasteful' LDREXD (double load from mem) in the ISR, is that what you saying?
What is "foreground process" , main execution?
I understand the note in the manual like this. Hard to test anyway :(
"foreground process" is that code which is interrupted.
42Bastian Schick you very most likely right, but how do I jump to the exact note / para you referring too:
https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Application-Level-Memory-Model/Memory-types-and-attributes-and-the-memory-order-model/Atomicity-in-the-ARM-architecture?lang=en
I do see someone's C11 atomic implementation and it deff does ldrxed first, but I thought that's only because it does the spinlock .
Wait, no dummy "ldrexd" needed:a) 1) "main" => ldrexd => sets lock2) "main" (no ISR) => strexd succeeds => no new datab)1) "main" => ldrexd => sets lock2) isr => strexd (succeeds or not, does not matter as you wrote), but if succeeded, lock is cleared3) "main" => strexd fails => follow with an "ldrexd" and "clrex" to get new data
Edit: Typo
heh.. Ok, need to try this.
42Bastian Schick
.. And probably an wfi can be inserted in my "main" , after a successfull strexd (no new data from isr..)
WFI might be good, but check also: "A3.4.5 Load-Exclusive and Store-Exclusive usage restrictions"
_Any_ other STREX will clear the lock. So I would not rely on this and rather use an (atomically written) 32bit value as indicator for new data.
I believe - from this ARM support forum - ldr/str ex have the inner/outer (don't know the exact term) concept, i.e:
ldrex{ ldrex, strex} strex <-- holds, i.e the inner only unlocks the latest ldrex . So I don't think / agree about _ANY_ if that's what you meant. In separate memory locations .
But yea, if I'm into using atomic words of lesser size, then I'm better off to do just a typical ringbuffer to copy buffers, and that's not what I was wondering about.
There is no general statement about the locked area, the size depends on architecture and implementation. But for what I know, it is a single bit per core. No inner/outer stuff here. Else "clrex" would not make any sense.
There is also no "nesting". Any strex clears the lock.
Edit: Typo.
Ok, what I was referring to, prob out of scope, but this (sorry its for v7-M arch link ):
https://community.arm.com/developer/ip-products/processors/f/cortex-m-forum/10361/ldrex-strex-on-the-m3-m4-m7
... and the sub-post note in :
"
The sequence {ldrex, {ldrex, strex}, strex} should work correctly, IMO. The ldrex of the inner pair "overwrites" the effect of the ldrex of the outer pair. After the inner pair unwinds and the execution is at strex of the outer pair, it does not succeed. The outer pair runs again, hoping that the inner pair does not interfere thi ....."
see post
Having two (or more) ldrex in sequence with different addresses is IMHO an programming error. But this is by my understanding. I cannot cite any manual to "prove" this.