data synchronization without using semapore in C

后端 未结 3 712
甜味超标
甜味超标 2021-01-16 03:13

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

3条回答
  •  迷失自我
    2021-01-16 03:40

    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.)

提交回复
热议问题