-
Notifications
You must be signed in to change notification settings - Fork 377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is use of LDREXW & STREXW in micros() correct? #609
Comments
Any ref info for correct use or note on the direction of the failure? It is odd that that single var resides isolated in a big block (2K?) of RAM based on Frank B's posting of linker data. |
Paul: Yes, because it is not needed for the T4. Tim: That is a completely different topic |
Not this topic? in delay.c :: uint32_t micros(void) Some means of atomic read is needed? |
No, the linkage issue with large unused RAM areas is a different topic:) Paul: It's (still) a interrupt-detector. The loop repeats when an interrupt happened. Not more, not less. It's completely OK for the Teensy 4 (even if the variable would be local) . If you want to use it different, you need to rewrite the code - more than this. |
There are way more important things. Things that are broken. This is not broken. |
Quick look I don't see any other suggestions for use where this {__LDREXW... __STREXW} is broken. Seems it is deprecated in 'mainstream' ARM beyond M4/M7. Ref notes found show use for a single value - here we need two volatile DWORDS. If attention were given here - then the RAM issue might be resolved - yes perhaps ref address to a 'local' var? - and from OP not clear it wasn't part of the concern at hand. Indeed in between {__LDREXW... __STREXW} as tested any interrupt causes it to repeat, as without an interrupt the values should be safely copied? |
It works very reliable is has way less impact than disabling interrups. Tim: Local var: #594 |
As mentioned on the forum, I created this issue mainly as a reminder to look at this more carefully at some point in the future. I absolutely agree many much more important things are broken and need to be investigated & fixed before this. I did not intend to start a discussion, but here we are... Found this today which specifically mentions Cortex M7's behavior. It does say the exclusive access tag is cleared if an exception occurs. Since systick is an ARM exception rather than a normal interrupt, I'm pretty sure that means this does indeed work. |
Just wondered what triggered your concern - thanks for the link - seems that is maybe a new look at it. Would be interesting to find the systick faux interrupt didn't count - but given the millions of iterations in testing seems something odd would have show up. I can see writing a test to confirm it triggering in 'that while' and repeating on systick update. |
I think i posted a test on the beta thread |
The 1000+ message thread in 2019, right?
No LDREX or CLREX in the interrupt. Most documentation on these instructions doesn't mention the exception behavior to clear the exclusive access flag. Still not clear to me if the clear of exclusive access applies to interrupts or only to ARM exceptions, though in this case systick definitely is an ARM exception. Eventually I would like to use this in other places where we're regularly disabling interrupts... Again, not my intention to turn this into a lengthy discussion. |
I think we found 2019 that it triggers on any interrupt. |
Added a comment to the code. f452eb4 |
Wrote a sketch that showed me what I expected to see - more 'testy' than anything I wrote before. NOTE: Test results unchanged with Global or local copy of: uint32_t MYsystick_safe_read; // micros() synchronization
Output: Pauses 10 secs every 1M loops()
Results: Seems to be working as expected
`void setup() { } uint32_t inMicros = 0; inMicros = toMicros; #include "arm_math.h" // micros() synchronization |
minor code edits - oddity explained by code call order where millis() was changing between calls |
The systick_isr() and systick_isr_with_timer_events() functions don't access the systick_safe_read variable which micro() is using for synchronization.
The text was updated successfully, but these errors were encountered: