2012-01-19 19 views
5

私が使用しているマイクロコントローラがあります。デバッグの際には、ROMからハードコーディングされた関数を呼び出す必要があります。テクニカルリファレンスは、これを実行する方法を示しています。ROM内の関数へのポインタ

# define Device_cal (void(*)(void))0x3D7C80 

やプロシージャを呼び出すには、次のようになります

(*Device_cal)() 

私は実際にここに何が起こるかを理解することはできませんので、私の質問は: それはどのように動作しますか?

答えて

3

#define原因(*Device_cal)()

(*(void(*)(void))0x3D7C80)() 

void(*)(void)voidをとり、voidタイプを返す関数ポインタの宣言です。 (*())は、式(0x3D7C80)の次のトークンのキャストを表します。したがって、これは位置0x3D7C80のデータを関数として扱うように求められます。最後の()は引数なしで関数を呼び出します。

7

void (*) (void)はタイプです。パラメータをとらず、voidを返す関数へのポインタです。

(void(*)(void)) 0x3D7C80は、0x3D7C80整数をこの関数ポインタにキャストします。

(*Device_cal)()は関数を呼び出します。

(Device_cal)()はまったく同じことを行います。

括弧は*Device_calDevice_calです。そうしないと、整数へのキャストの方が優先順位が高くなりません。

2

よく、あなたは関数へのポインタを定義し、それを呼び出します。 void(*)(void)は、引数を取得しない関数へのポインタを意味し、voidを返します。 0x3D7C80をその型にキャストして呼び出すと、基本的にそのアドレスが0x3D7C80であるという関数が呼び出されます。すぐにコンパイルする前に、これに拡張する

0

固定されたメモリ位置にある関数への一時的な(名前のない)ポインタを作成し、逆参照によって呼び出すシンボルが貼り付けられます。

2

これが答え(つまり、すでに十分行われている)が、いくつかのアドバイスではありません。

私が代わりに以下の方法をお勧めします:

typedef void (*tVOID_ROMFUNCTION_VOID)(void) ; 

tVOID_ROMFUNCTION_VOID Device_cal = (tVOID_ROMFUNCTION_VOID)0x3D7C80 ; 

Device_cal() ; 

あなたが世界の任意の数を作成することができますこの方法通常の静的にリンクされた関数のように見えます。また、プリプロセッサのマクロを同時に混乱させることもありません。

さまざまなシグネチャで異なる関数ポインタ型を作成することによって、コンパイラはあなたのためにいくつかのパラメータ型チェックを実行することができます。

+0

私はこの答えがより多くの票を持っていないことに驚いています。これはマクロソリューションよりもはるかにクリーンです。 – tomlogic

+0

@tom:ありがとうございますが、私が言ったように公平であることは、質問された質問に対する答えではなく、尋ねていたことをする良い方法です。 – Clifford

関連する問題