データポインタとコードポインタ

テクニカル・ノート 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)
    {
    ;
    }
    void *p = (void*)fun;
    または、pragma type_attributeを使用します。
    #pragma type_attribute=__nearfunc

    void fun (void)
    {
    ;
    }

    void *p = (void*)fun;

 

全ての製品名は、それぞれの所有者の商標または登録商標です。

申し訳ございませんが、弊社サイトではInternet Explorerをサポートしていません。サイトをより快適にご利用いただくために、Chrome、Edge、Firefoxなどの最新ブラウザをお使いいただきますようお願いいたします。