2
\$\begingroup\$

I read the documentation about interrupts in Arduino and there is this example code:

int pin = 13;
volatile int state = LOW;

void setup() {
  pinMode(pin, OUTPUT);
  attachInterrupt(0, blink, CHANGE);
}

void loop() {
  digitalWrite(pin, state);
}

void blink() {
  state = !state;
}

Well, it is not good example, but for my question is good enough.

What if in function blink() is some non-atomic operation. Let's say, I have to change several variables, call some function, etc. Should I call noInterrupts() before, or are the interrupts disabled automatically?

void blink() {
   noInterrupts(); // Disable interrupts
  // some complex work, here.
  interrupts(); // Enable interrupts
}

I looked into hardware/arduino/cores/arduino/WInterrupts.c in my Arduino IDE directory, but I cannot find any information there.

And one more thing: Why should I declare any variable in interrupt routine as volatile?

\$\endgroup\$
5
\$\begingroup\$

Looking at http://code.google.com/p/arduino/source/browse/trunk/hardware/arduino/cores/arduino/WInterrupts.c#155 you can see that your interrupt handling function is executed from within the interrupt handler's context.

Only one interrupt handler can be running at a time, so you can be sure that no interrupts will occur while your blink() routine is running. You do not need to call noInterrupts() or interrupts() from within your handler function.

Because your function will run in interrupt context, it is important to return as quickly as you can to allow other interrupts (and foreground) code to continue executing.

Any variable used in your interrupt handler, which is also used by non-interrupt code should be volatile. This tells the compiler that it must re-read the memory location on every access and not cache it. Without volatile, an interrupt handler might change the variable between instructions leaving foreground code with an invalid cached value.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you. I can see it now. In interrupt vector is stored address of my 'blink()' function. So when interrupt happens, microcontroler itself disables interrupts, stores PC register and so on. Then it jumps into my subroutine (blink). Am I right? \$\endgroup\$
    – vasco
    Oct 4 '11 at 11:31
  • \$\begingroup\$ Yes, the function pointer for your handler is stored, then called from inside the ISR \$\endgroup\$ Oct 4 '11 at 12:42
  • \$\begingroup\$ Followup question: is declaring variables as volatile only important if they are written to in both places? Or should I declare them as volatile even if my ISRs only read from them? \$\endgroup\$
    – Engineero
    Apr 16 '14 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.