This page is also available in 3 other languages

volatile

[Variable Scope & Qualifiers]

설명

volatile 변수 qualifier 로 알려진 키워드이며, 변수의 자료형 앞에 사용되어, 컴파일러와 후속 프로그램이 변수를 다루는 방법을 바꾼다.

변수를 volatile 로 선언하는 것은 컴파일러에 대한 지시다. 컴파일러는 C/C++ 코드를 기계어로 번역하는 소프트웨어이며, 이것은 아두이노 안의 Atmega 칩을 위한 실제 명령이다.

특히, 그것은 컴파일러가 변수를 저장 레지스터가 아니라 RAM으로 부터 변수를 로드하도록 지시하는데, 그것은 프로그램 변수가 저장되고 다루어지는 임시 메모리 위치이다. 어떤 조건에서, 레지스터에 저장된 변수에 대한 값은 부정확할 수 있다.

변수는 그 값이 나타나는 코드 섹션을 의 넘어 바뀔 수 있을 때(예:동시 실행 thread 와 같은) 마다 volatile 로 선언되어야 한다. 아두이노에서, 이것이 발생할 만한 유일한 장소는 인터럽트와 관련한 코드섹션이며, 인터럽트 서비스 루틴이라 불린다.

int 또는 long volatiles

volatile 변수가 byte(예 16비트 int 또는 32비트 long)보다 크면, 마이크로컨트롤러가 한 단계에 읽을 수 없는데, 왜냐면 그건 8비트 마이크로 컨트롤러이기 때문. 이것은 여러분의 메인 코드 섹션(예 loop)이 변수의 첫 8비트를 읽는 동안, 인터럽트는 이미 두번째 8비트를 바꿀 수도 있다는 걸 뜻한다. 이것은 변수에 임의 값을 만들 거다.

치료:

변수가 읽히는 동안, 인터럽트는 비활성화되어야 하며, 따라서 변수들은 그들이 읽히는 동안 비트를 건드릴 수 없다. 이것을 하는 여러 방법이 있다:

  1. LANGUAGE noInterrupts

  2. use the ATOMIC_BLOCK macro. Atomic operations are single MCU operations - the smallest possible unit.

예제 코드

// 인터럽트 핀이 상태를 바꿀 때마다 LED를 토글한다

int pin = 13;
volatile byte state = LOW;

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

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

void blink() {
  state = !state;
}
#include <util/atomic.h>  // this library includes the ATOMIC_BLOCK macro.
volatile int input_from_interrupt;

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  // code with interrupts blocked (consecutive atomic operations will not get interrupted)
  int result = input_from_interrupt;
}

더보기