I need to have data synchronization in my code. Currently I am accessing a global value inside interrupt and also in a local function which may corrupt the data if interrup
What you need is atomic access to the data. If it is a single variable and you can guarantee that access is atomic, then that is enough. However, this involves disassembling the C code and see what you ended up with. And even if the machine code ended up as atomic (single instruction), it won't be portable.
If you have a modern compiler with C11 support, you can declare the shared variable as _Atomic
and that will solve the issue.
Another alternative is to simply shut off the particular interrupt during variable access in the caller. This will however disrupt real-time performance and you might miss out interrupts.
The universally "best" solution might be to invent a semaphore by yourself. Example:
// volatile to prevent dangerous compiler optimizations; does not solve re-entrancy
volatile uint32_t data;
volatile bool guard;
void ISR (void)
{
if(!guard)
{
data = SOME_REGISTER;
}
}
void main (void)
{
...
guard = true;
uint32_t local = data;
guard = false;
}
In the above example no atomic access is guaranteed at all, not even to the guard
variable. However, it is no longer necessary, because at the point where main()
is about to read the data, the guard
is guaranteed to be set. If the interrupt would kick in during the read, it wouldn't corrupt the data.
The only downside of this solution is that you will be missing out updating data
when the guard is set. If this is an issue, you will have to implement some manner of temporary storage.
(Note that this code does not result in "memory barriers", so on complex multi-core processors, this method might not work and volatile
will not necessarily result in a memory barrier. On ordinary microcontrollers it will work just fine though.)