2017-12-28 48 views
2

特定のアドレス(たとえばDouble function indirection in C)から関数を呼び出す必要がありますが、まったく同じではありません。私は、マッピングテーブルからポインタを引き出し、動的に生成された関数ポインタを操作することができます。例えば、私はコールのこのタイプを避けたい:GCC on ARM Cortex M3:特定のアドレスから関数を呼び出す

((int)(*)(void*)) compute_volume = ((int)(*)(void*)) 0x20001000; 

int vol = (*compute_volume)(); 

代わりに、私はcompute_volume()機能が異なる画像によって提供されることを除いて、以下のことを実現するために、リンカに提供記号または他の方法のいくつかの並べ替えを使用することを好むだろう、おそらくこのような何か:つまり

extern int compute_volume(void); 

vol = compute_volume(); 

は、私はこのように毎回記号や計算の変更をフラッシュを変更するか、上書きの必要性を減らす、複数の画像の中に私のコードを分割していきます。

どのような提案やアイデアですか?

+0

関数ポインタはそれを行うように設計されています。しかし、構文が厄介な場合は、この場合、 '#define'または多分[typedef](https://stackoverflow.com/questions/4295432/typedef-function-pointer) –

+0

またはhttp:// blogを使用することができます.atollic.com/gnu-gcc-on-arm-cortex-devices-code-and-data-on-special-memory-addresses-gnu-ld-linkerを使用する –

+0

これは*マイクロコントローラのフラッシュメモリにはウェアレベリングがないため、毎回フラッシュ全体を書き換えるのに比べて更新サイクルが増えません。 –

答えて

0

同じフラッシュ領域に常駐するジャンプテーブルを定義することができます(リンカとプラグマでその領域を定義することができます)。呼び出されると、目的の関数にジャンプします。

ファームウェアの部分では、関数のアドレスを「渡す」ことを参照するシンボルのみを定義します(同じ領域に常に置い​​ておくと、将来の更新をさらに容易にします)。ファームウェアパートIIでは、ファームウェアパートIで参照していたアドレススペースにあるジャンプテーブルを作成し、実際の関数を呼び出します。

私はそれを正しく説明しているとは確信していませんが、これはあなたの問題をどのように解決するかという考えを与えるはずです。リンクリングØを使用すると、ジャンプテーブルコードを1か所に配置するのに役立ちます。

関連する問題