I happened to see https://github.com/PaulStoffregen/cores/blob/master/teensy3/yield.cpp
specifically this comment // TODO: does this need to be atomic?
shortly before reading https://mcuoneclipse.com/2013/08/14/volatile-can-be-harmful/
specifically:
ARM Memory Barrier Instructions
Below is the FreeRTOS source which creates a context switch within an interrupt service routine:
Notice the two assembly instructions at the end: dsb (data synchronization barrier) and isb (instruction synchronization barrier). They ensure that data and instructions get serialized. See this ARM Infocenter article for details.
I cannot say that I fully understand all that, but it does seem to be an answer. __asm volatile("dsb"); __asm volatile("isb"); couldn't hurt, to be sure all bus reads and writes are complete before returning. A lower bar than atomic.
specifically this comment // TODO: does this need to be atomic?
shortly before reading https://mcuoneclipse.com/2013/08/14/volatile-can-be-harmful/
specifically:
ARM Memory Barrier Instructions
Below is the FreeRTOS source which creates a context switch within an interrupt service routine:
Code:
void vPortYieldFromISR(void) {
/* Set a PendSV to request a context switch. */
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is completely
within the specified behavior for the architecture. */
__asm volatile("dsb");
__asm volatile("isb");
}
I cannot say that I fully understand all that, but it does seem to be an answer. __asm volatile("dsb"); __asm volatile("isb"); couldn't hurt, to be sure all bus reads and writes are complete before returning. A lower bar than atomic.