2014-11-25 2 views
0

은 프로세서의 16 비트 레지스터의 많은 레지스터 경우 우리가 (uword *) 포인터가 필요합니까 왜왜 16 비트 레지스터에 대한 포인터가 uword입니까?

#define CAN_REG01    (*((uword volatile far *) 0x200000)) 

같이 정의하고 그 값은 여전히 ​​16 비트이다가 된 것으로?

+1

나는 그 질문을 이해하지 못한다. 이 간단한 정의는'CAN_REG01 = ...'또는 실제로는'uword regvalue = CAN_REG01'과 같은 것을 쓸 수 있도록 해줍니다. 너가 이해하지 못한게 뭐야? –

+1

왜 포인터로 캐스팅해야하는지 궁금하십니까? 아니면'uword'가 (표준 타입이 아니기 때문에) 궁금합니다. 문제를 조금 더 자세히 설명해 주시겠습니까? –

+0

'0x200000'은'unsigned int' 타입이고, 포인터에 캐스트하지 않고 역 참조 할 수 없습니다. – mch

답변

1

데이터 시트를 살펴보면 CAN_REG01의 주소가 0x200000임을 알게 될 것입니다.

SFR (특수 기능 레지스터)에 쓰고 읽을 수있는 읽을 수있는 것을 제공하기 위해 일반 정의 변수 이름처럼 CAN_REG01이라는 이름을 사용할 수 있도록 정의한 사람이 있습니다.

0x200000에 쓰기를 원한다고 컴파일러에게 알려야하므로 포인터로 처리해야합니다. 또한이 포인터 뒤에있는 데이터의 크기를 컴파일러에 알려줘야합니다. 분명히 CAN_REG01 레지스터의 크기는 uword입니다 (특정 플랫폼에서 그 의미가 무엇이든). 컴파일러가이 주소에 대한 액세스를 최적화하지 않도록하려면 volatile을 추가해야합니다. 일부 프로세서 내부 또는 인터럽트는 코드에서 독립적으로 변경할 수 있기 때문입니다. 또한 컴파일러는 마지막 레지스터 만 중요하다고 생각하기 때문에 컴파일러는이 레지스터에 연속 할당을 제거 할 수 있습니다.

이 방법은 임베디드 플랫폼 베어 메탈 컴파일러에서 매우 일반적입니다.

+0

고맙습니다. 내 설명이 명확하지 않았다. uword는 32 비트를 의미하지만 레지스터는 16 비트입니다. 그게 내가 궁금해하는거야 : 왜 (* ((단어 휘발성 멀리 *) 0x200000)), 여기서 단어 == 16 비트? – elusive

+2

'word '가 16 비트라면'uword'도 16 비트입니다. 유일한 차이점은 서명입니다. –