2017-12-14 5 views
3

나는 컴퓨터 공학을 공부하고, 여기에 교사들은 항상이 같은 μC 주소를 정의라고 우리에게 이야기했다 :이 매크로 본문에 왜 형식 변환이 있습니까?

#define FIO0DIR (* (unsigned int *) 0x2009C000) //GPIO direction register from the lpc1769

하지만 그들은 정말 이유를 설명하거나 무슨 일이 일어나고 있는지 않습니다.

제 궁금한 점은 왜 캐스트가있는 것입니까?

+1

이 코드는 깨졌습니다. '휘발성의 unsigned int *'이거나 더 나은'volatile uint32_t *'이어야합니다. 'volatile' 키워드는 하드웨어 레지스터에 대한 포인터를 선언 할 때 필수적입니다. – Lundin

+2

아니요, 휘발성 키워드가 있어야합니다. 그렇지 않으면 결국 컴파일러가 이상한 최적화를 수행 할 수 있습니다. LPCXpresso는 gcc를 사용하며 gcc는 매우 적극적인 최적화 기능을 제공합니다. 아마 당신은 최적화가 비활성화되어 있기 때문에 작동합니다. '-O3'을 시도하고 버그가 튀어 나오는 것을 지켜보십시오. – Lundin

+0

네 말이 맞아, 나는 최적화 옵션을 건드리지 않았고 분명히 -O0로 기본 설정되어있다. 이것이 지금까지 모든 것이 효과가 있었던 이유입니다. – Arrrow

답변

5

어째서 캐스트입니까?

0x2009C000은 정수 상수이기 때문에. 주소가 아닙니다. C 유형 시스템은 대상 아키텍처가 아닐지라도 정수와 주소를 구별합니다. 여러 가지 제약 조건이있는 변환을 허용하지만 두 유형은 이 아니며이 하나입니다.

적분 상수를 올바른 포인터 유형으로 바꾸려면 캐스팅이 필요합니다. 따라서이를 역 참조하고 해당 주소에있는 항목에 액세스 할 수 있습니다.

0

인용 C11, §6.5.3.2, 주소 및 간접 연산자

* 단항 연산자의 피연산자가 포인터 타입을 가진다. 그 자체에

0x2009C000정수 상수 (§6.4.4.1 장에서 언급 한 바와 같이)이 아닌 포인터 타입이다.

그러나이 정수 상수를 주소으로 사용하려고하며 값을 얻기 위해 주소를 비준해야하므로 캐스트가 있습니다.

캐스팅로서 부호 INT 포인터를 정수 상수 값 취급하도록 컴파일러에 지시하고, 참조 연산자는 메모리 위치에 저장된 값을 얻기 위해 포인터에 작용한다.

일반 적용 가능성으로 간주하지 마십시오. 정수 상수 값이 (유효한) 주소 위치를 나타낼 수 있는지 여부는 플랫폼과 환경에 크게 좌우됩니다.

0

컨트롤러가 주소 0x2009C000에 매핑되어 있지만 조작하려면 해당 주소에서 저장하거나 읽을 데이터 형식을 정의해야합니다. 그리고 이것은 C와 같은 고급 언어에서 어떤 유형의 데이터가 어떤 주소에 저장되는지, 길이 (바이트) 및 표현 (예 : 2의 보수로 정수)을 지정하는 것입니다. 따라서 :

(unsigned int *)0x2009C000 

은 부호없는 정수가 저장된 주소로 뷰 상수 0x2009C000을 의미합니다.

* ((unsigned int *)0x2009C000) 

는 부호없는 정수는, 지정된 어드레스에 저장 단순히 부호 정수 변수 저장되는 어드레스에 저장된 변수를 의미한다.

관련 문제