Electronic – arduino – When Arduino catch interrupt, is noInterrupts() called

arduinointerrupts

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?

Best Answer

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.