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 |