Using volatile often cited as a solution, but this is not entirely true. It often disguises the problem, since volatile will always make the code slower. If your only use is shown like this, then volatile will probably work.
It is probably best to use memory barriers with a single reader and a single record. Then it will be your code,
Highway:
volatile int *p = &flag; while (*p == false); flag = false; asm volatile ("" : : : "memory");
ISR:
flag=true asm volatile ("" : : : "memory");
Here, the barrier simply forces the compiler to execute the ARM str command at that point. The optimizer will not move the code before or after. You can also use swp or ldrex and strex depending on your ARM CPU. In addition, ring buffers are often used with ISRs and main lines because they do not need any special CPU support; only a compiler memory barrier.
See lock-free and, in particular, the search for lock-free and arm .
Edit: For additions,
Is there a way that I will not skip interruption at all?
It depends on the source of the interrupt. If this is a timer, and you know that the timer source can never be faster than XX , and no other interrupts are active in the system, then your current code will work. However, if the interruption comes from an external source, such as an Ethernet controller, a non-debuted keyboard, etc. Multiple interruptions are possible. Several times new interrupts occur even during the interrupt handler. There are different solutions depending on the source of the ISR. A ring buffer is typically used to queue work items from the ISR for the main row. For UART, a ring may contain actual character data. This could be a list of pointers, etc. It is difficult to synchronize the ISR with the main line when the connection becomes more complex; Therefore, I believe that the answer depends on the source of the interrupt. This is why every OS has so many primitives and infrastructure for this problem.
How do memory barriers solve the problem, does it have an effect when the code runs on a single processor?
Memory items do not completely eliminate the problem of missing interrupts; just like volatile not. They just make the window a lot smaller. They force the compiler to schedule loading or to store earlier. For example, the main loop of the line,
1: ldr r0, [r1] cmp r0, #0 ; xxx bne 1b ; xxx mov r0,#1 ; xxx str r0, [r1]
If a second interrupt occurs during xxx lines, your flag must be set twice, and you missed one interrupt. The barriers just make sure that the compiler puts ldr and str close to each other.
What is the expected behavior when using barriers between different contexts?
I see how the compiler locks memory, and the compiler does it before. This does not affect the context. There are various barriers; but they are mainly for multiprocessor projects.
Can sleeping in a while loop solve synchronization problems?
Not really, it's just more efficient use. The ARM WFI team can temporarily stop the CPU, and this will save energy. Usually this sleep () does on ARM. I think you need to change the relationship between ISR and mainline if this is a problem. It depends on the source of the ISR .