データポインタとコードポインタ
テクニカル・ノート 84583
アーキテクチャ:
AVR
コンポーネント:
compiler
更新日:
2018/08/25 14:21
はじめに
本テクニカルノートでは、データポインタを使用してコードメモリを参照するという間違った使用方法について説明します(この間違いは、 IAR AVR C/C++コンパイラによって検出されます)。
解説
以下のソースコードを使用すると、
void fun (void)
{
;
}
void *p = (void*)fun;
int main( void )
{
return 0;
}
以下のエラーメッセージが表示されます。
Error[Pe028]: expression must have a constant value ...\main.c
このメッセージが表示される背景
このメッセージは、「void *」ポインタがデータポインタであるために表示されます。データポインタは、コードメモリを参照する関数ポインタとは大きく異なります。このエラーは、コードポインタよりもデータポインタの方が小さいときに報告されます。-mtオプションを使用するとデフォルトのデータポインタが8ビットとなり、-msオプションを使用するとデフォルトのデータポインタが16ビットになります。
解決方法
- IAR AVR C/C++コンパイラバージョン6.10以降では、この類の問題を検出することができます。ソースを正しく書き直すと以下のようになります。
-
void fun (void)
{
;
}
typedef void (*f_p)(void);
f_p p = fun; - この問題を回避するには、コンパイラオプションの-v3 -msまたは-v6 -mhを使用して、データポインタとコードポインタが同じサイズになるようにします。
- ATxmega128D4などのXMEGAデバイスを使用している場合(すなわち、-v5デバイスを使用している場合)、-v5 -msオプションを使用し、なおかつ__nearfuncキーワードを使用してnearメモリに関数を配置します。
__nearfunc void fun (void)
または、pragma type_attributeを使用します。
{
;
}
void *p = (void*)fun;
#pragma type_attribute=__nearfunc
void fun (void)
{
;
}
void *p = (void*)fun;
全ての製品名は、それぞれの所有者の商標または登録商標です。