title: ISR cannot change extern struct field in C embedded
body: <p>I've got a problem with STM32F091RCT on Nucleo, which I use for controlling the stepper motor driver DRV8825.  </p>
  
  <p>The main goal of the code section below is to stop the stepper motor when it rotates too much, using interrupt from Hall switch and a magnet. I'm also using HAL libraries for STM32 and of course C language.</p>
  
  <p>I've got these files:</p>
  
  <p>motor.h:</p>
  
  <pre><code>typedef struct{
     volatile uint8_t STOP_FLAG
  } Motor;
  </code></pre>
  
  <p>motor.c:  </p>
  
  <pre><code>#include "motor.h"
  
  void ClearStopFlag(Motor *motor)
  {
    motor-&gt;STOP_FLAG = 0;
  }
  
  void SetStopFlag(Motor *motor)
  {
    motor-&gt;STOP_FLAG = 1;
  }
  
  uint8_t GetStopFlag(Motor *motor)
  {
    return motor-&gt;STOP_FLAG;
  }
  
  void Init(Motor *motor)
  {
    ClearStopFlag(motor); 
  }
  
  void Rotate(Motor *motor)
  {
    int i;
    for(i = 0; i &lt; 50; i++)      // every iteration is a motor step
    {
      if(GetStopFlag(motor)) break;
      // irrelevant code switching the output used for driver step input ----
    }
  }
  
  void Disable(Motor *motor)
  {
    // Code that sets the GPIO pin responsible for ENABLE pin in the driver ----
  }
  </code></pre>
  
  <p>hall.c:  </p>
  
  <pre><code>#include "motor.h"
  #include "exec.h"
  
  extern Motor m;
  
  void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  {
    SetStopFlag(&amp;m);
  }
  </code></pre>
  
  <p>exec.c:</p>
  
  <pre><code>#include "hall.h"
  #include "motor.h"
  
  Motor m;
  
  void SomeFunction(void)
  {
    Init(&amp;m);
    Rotate(&amp;m); // here GPIO ISR in hall.c doesn't set the STOP_FLAG while Rotate() is executing
  }
  </code></pre>
  
  <p>main.c:</p>
  
  <pre><code>#include "exec.h"
  int main(void)
  {
    SomeFunction();
    return 0;
  }
  </code></pre>
  
  <p>First of all, the original code is much more complex, I have not included here some headers which are used for function prototypes, other Motor struct fields, other functions etc. I don't have access to the code right now it is also much more cleaner that way.  </p>
  
  <p>I've tested it a lot and the problem is that the GPIO interrupt callback function cannot change the STOP_FLAG variable. This is how it behaves: </p>
  
  <ul>
  <li>the interrupt works well - when i try to turn on the diode in interrupt section - it turns on; when i try to <strong>disable the driver using Disable() function from motor.c it works and sets the proper GPIO port</strong></li>
  <li>when i try to set the STOP_FLAG in ISR whitout a function, that is using <code>m-&gt;STOP_FLAG = 1;</code> it doesn't work</li>
  <li>when i call the SetStopFlag() function from exec.c (eg. in SomeFunction() before the Rotate() line) it works properly</li>
  </ul>
  
  <p>Does somebody know why hall.c has a problem accessing the struct field?</p>