임베디드 시스템에서 프로그래밍 할 때 디바이스 드라이버나 직접 디바이스를 제어하는 응용 프로그램
을 작성할 때 메모리에 직접 접근하여 프로그래밍을 하는 경우가 많습니다. 그럴 경우 보통 전역 변수
에 주소를 담아서 포인터로 제어하려고 하는데 사실 매크로로 선언하면 편하기도 편하고 실수로 변수
에 엉뚱한 값을 넣게 되는 경우를 사전에 막을 수도 있습니다.
반대로 샘플 코드등에 매크로로 선언된 직접 접근 방법을 사용하였을 경우 바로 이해가 가는 않는 경
우가 간혹 있는데...(물론 저 같은 경우를 말합니다;;;) 매크로로 메모리 직접 접근 방법을 알아두면 상
당히 편합니다.
우선 이 매크로를 이용한 메모리 직접 접근 방식의 모양은 다음과 같습니다.

#define <DEVICE> (*(volatile unsigned <type>*) <address>)
DEVICE : 매크로 이름을 적당히 지어주세요;;
type : char, int와 같은 데이터 타입. 제어할 바이트 수를 고려해서 지정.
address : 0x00000010 과 같은 32비트 시스템일 때 제어할 디바이스의 32비트 주소
대충 사용 예는 다음과 같습니다.
DEVICE |= 0x1 << 3;
//디바이스에 0x1값을 3만큼 좌측 시프트해서 OR 연산으로 DEVICE에 갱신하라는 뜻이 겠죠...
그리고 위의 매크로 정의의 의미를 설명하겠습니다.
우선 주소 값에 값을 대입하여 바로 제어할 수 없으므로 주소 값에 포인터 연산자를 붙여 캐스팅하애햐
고...
(0x00000010을 예로 들면 (*)0x00000010)
그 다음 그 주소 값에 직접 값을 값을 넣기 위해서는 다시 참조 연산자를 붙여야 합니다.
( *(*)0x00000010 이 되겠죠...)
위의 경우 몇 바이트를 제어 할지 않나와 있습니다. 그래서 데이터 타입을 붙입니다.
( 한바이트 제어면 *(char*)0x00000010 )
( 4바이트 제어면 당연히 *(int*)0x00000010 )
그리고 제어면 당연히 산술 연산이 아니라 논리 연산만 하겠죠....unsigned를 붙입니다.
( *(unsigned char*)0x00000010 )
조금 더 손봐야합니다...임베디드 프로그래밍의 경우 컴파일러에 의해 최적화를 받게 되면 코드가 어
떻게 될지 모릅니다...당연히 volatile을 붙여야 겠죠... 그래서 나오는 최종 모습이 아래와 같습니다.
=> *(volatile unsigned char*)0x00000010
매크로로 만들기 위해선 당연히 #define로 선언해야하고...
#define DEVICE *(volatile unsigned char*)0x00000010
당연히 이게 끝이 아닙니다....매크로의 특성 상 코드에 치환 될 뿐이므로 우선 순위가 어떻데 될지 모
릅니다. 당!연!히! 전체 괄호로 묶어 주세요!!! 최종 모습은 다음과 같습니다.
#define DEVICE (*(volatile unsigned char*)0x00000010)

 

출처 : http://blog.naver.com/no1rogue/30076447091

+ Recent posts