volatile
Original Page : http://blog.naver.com/nsangil82/80031406565

volatile는 C의 키워드중 하나이다. 아마 처음보거나 익숙하지 않은 키워드일 것이다. 이 녀석을 이해하기 위해서는 컴파일러의 옵티마이즈(Optimize)옵션에 대해서 먼저 알아야 한다. 옵티마이즈 옵션은 한마디로 C 컴파일러의 코드 최적화 옵션을 말한다. 아래의 코드를 한번 보자.

예1)
*(unsigned int *)0x70A0 = 0x4001; //0번
*(unsigned int *)0x70A0 = 0x4002; //1번
*(unsigned int *)0x70A0 = 0x4003; //2번
*(unsigned int *)0x70A0 = 0x4004; //3번
*(unsigned int *)0x70A0 = 0x0550; //4번


위 코드를 컴파일러의 입장에서 보면 0~3번은 아무 필요없는 코드가 된다. 따라서 컴파일러는 코드 최적화를 위해 0~3번까지의 코드를 전부 제거하고 4번 코드만 컴파일해서 어셈블리 코드를 만든다. 이것이 컴파일러의 옵티마이즈다.

사실 소프트웨어인 컴파일러의 입장에서 위의 옵티마이즈는 당연한 것이다. 그러나 하드웨어적(임베디드 시스템)인 입장에서 이러한 C 컴파일러의 옵티마이즈는 치명적인 결과를 불러이르킬 수 있다. 만약 위의 예1의 "0x70A0" 라는 주소가 단순한 메모리 주소가 아닌 peripherial에 접근하는 MMR(Memory Mapped Register)이라고 생각해보자. 그렇다면 이 레지스터는 단순히 값을 저장하는 역활이 아닌 peripherial을 제어하는 역활을 한다. 따라서 위 코드의 0~4번 코드 모두는 맡은 바 역활이 다 있다. 따라서 옵티마이즈 당하면 안되는 코드들이다. 바로 이때 쓰는 C키워드가 "volatile"라는 키워드다. volatile 키워드를 써서 올바로 코드를 바꾸면 아래와 같다.

예2)
*(volatile unsigned int *)0x70A0 = 0x4001; //0번
*(volatile unsigned int *)0x70A0 = 0x4002; //1번
*(volatile unsigned int *)0x70A0 = 0x4003; //2번
*(volatile unsigned int *)0x70A0 = 0x4004; //3번
*(volatile unsigned int *)0x70A0 = 0x0550; //4번

즉 hardware 적으로 꼭 필요하나 software 관점에선 불필요한 코드의 옵티마이즈를 막기위해서 "volatile"라는 키워드가 필요한 것이다. 정리해서 volatile 키워드가 필요한 경우는 아래와 같다.

* memory-mapped periherral registers

* 인터럽트 서비스 루틴에 의해 수정되는 전역변수

* 멀티 태스킹 또는 멀티 쓰레드 에서 사용되는 전역변수


임베디드 프로그래밍 관련 서적 집필로 유명한 Michael Barr는 그이 저서 "Programming Embedded Systems in C and C++"에서peripherial을 억세스 할때는 잔말 말고 무조건 volatile 키워드를 사용하라고 우리에게 협박(?)까지 하고 있다고 한다.



신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Proneer

댓글을 달아 주세요

  1. ㅡㅡ

    역활 ....... 맞춤법 ..... 역할입니다.

    2015.08.19 15:54 신고 [ ADDR : EDIT/ DEL : REPLY ]


티스토리 툴바