Data pointers와 code pointers
기술노트 84583
아키텍처:
AVR
컴포넌트:
compiler
업데이트:
2021-05-06 오후 3:38
소개
본 기술 노트는 메모리 코드영역(IAR AVR C/C++ 컴파일러가 감지하는)을 가리키기 위한 DATA포인터의 일관성 없는 사용에 대해 설명합니다.
논의
아래 소스코드를 보시면...
void fun (void)
{
;
}
void *p = (void*)fun;
int main( void )
{
return 0;
}
...다음의 에러메시지가 발생합니다:
Error[Pe028]: expression must have a constant value ...\main.c
에러메시지에 대한 배경지식
포인터 "void *"는 DATA포인터이기에 해당 메세지가 발생합니다. 이 포인터의 형식은 메모리 코드영역을 가리키는 FUNCTION포인터의 형식과 매우 다릅니다. 본 에러메시지는 DATA 포인터가 CODE포인터보다 작기 때문에 발생합니다. -mt 옵션을 사용할 경우 기본 DATA포인터는 8비트이고, -ms 옵션을 사용할 경우 기본 DATA포인터는 16비트입니다.
해결책
- IAR AVR C/C++ 컴파일러 버전 6.10(혹은 상위버전)은 이러한 문제를 감지하는 기능을 갖추었습니다. 올바른 소스 코드 작성법은 다음과 같습니다:
-
void fun (void)
{
;
}
typedef void (*f_p)(void);
f_p p = fun; - 해당 문제를 피하기 위해 -v3 -ms 나 -v6 -mh 컴파일러 옵션을 사용하여 데이터 포인터와 코드 포인터의 크기를 같도록 하세요.
- ATxmega 128D4와 같은 xmega 장비를 사용하는데, -v5 장비라면 -v5 -ms 옵션을 사용하세요. 단 __nearfunc 키워드를 사용하여 함수를 'near memory'에 배치하세요.
__nearfunc void fun (void)
또는 pragma type_attribute를 사용하세요:
{
;
}
void *p = (void*)fun;
#pragma type_attribute=__nearfunc
void fun (void)
{
;
}
void *p = (void*)fun;
모든 제품 이름은 해당 소유자의 상표 또는 등록 상표입니다.