본문 바로가기
프로그래밍 언어/c(임베디드)

volatile 지시자

by [Akashic Records] 개발의선지자 2024. 5. 8.

C언어 컴파일러 지시자 중에 'volatile' 지시자에 대해 포스팅한다.

 

MCU FW 프로그래밍을 하다 보면 레지스터를 제어하기 위해 같은 주소에 여러번 값을 여러번 쓰는 경우가 빈번하고,  앞에 volatile 키워드를 사용하는 경우를 볼 수 있다. 

 

※사용법 

원형 : volatile [type] [variable_name];

ex) *(volatile unsigned int *)0x8CFF = 0x8001, volatile int num1;

 

아래와 같은 상황들에서  volatile을 제대로 사용하지 않아서 문제 발생 가능성이 있다.

 

  • 컴파일화 최적화를 사용하지 않으면 제대로 동작하는 코드가 최적화만 사용 시 
  • 인터럽트를 사용하지 않으면 잘 동작하는 코드가 인터럽트 사용시
  • 메모리 주소를 가진 I/O 레지스터 사용시
  • 멀티 태스킹을 지원하는 운영체제 환경에서 두 개 이상 태스크 실행 시 

변수를 선언할 때 앞에 volatile을 붙이면 컴파일러는 해당 변수를 최적화에서 제외하여 항상 메모리에 접근하도록 한다. 즉, volatile 변수를 참조할 경우 레지스터에 로드된 값을 사용하지 않고 매번 메모리를 참조한다.

 

사용 상황

1) 컴파일러 최적화 사용 시 -> 최적화 방지

int i = 0;

while (i < 100)
    i++;

printf("%d\n", i);    // 100

컴파일러는 이 코드를 최적화하여 while 반복문을 없애버리고 i에  100을 할당해버립니다(Visual Studio의 /O2 옵션, GCC의 -O3 옵션)

 

여기서 i volatile로 선언하면 반복할 때마다 항상 i의 메모리에 접근해야 하므로 컴파일러는 while 반복문을 없애지 않습니다.

volatile int i = 0;    // volatile로 선언하여 항상 메모리에 접근하도록 만듦

// 항상 i의 메모리에 접근해야 하므로 컴파일러는 반복문을 없애지 않음
while (i < 100)
    i++;

printf("%d\n", i);    // 100

 

2) 인터럽트를 사용하지 않으면 잘 동작하는 코드가 인터럽트 사용시 -> 인터럽트 핸들러가 값을 변경하는 전역 변수

 

3) 멀티 태스킹을 지원하는 운영체제 환경에서 두 개 이상 태스크 실행 시 -> 멀티 스레드 응용 프로그램  전역 변수

 

출처 : 임베디드 시스템 뚝딱뚝딱

'프로그래밍 언어 > c(임베디드)' 카테고리의 다른 글

가변인자 함수 + 디버깅 매크로  (0) 2024.08.16
구조체 & 공용체 [1]  (0) 2024.07.18
LSM/MSB , 리틀 엔디안 / 빅 엔디안  (0) 2024.07.16
while문 사용법  (0) 2024.07.13
비트 마스크  (0) 2024.05.22