ブート パーティションとアプリケーション パーティションの間で共有する必要がある TCP/IP スタックがあります。スタックはブート コードで初期化され、ブートとアプリケーションの両方がスタックを使用します。両方のパーティションは同じフラッシュ メモリ モジュールにありますが、異なるフラッシュ セクションにあるため、互いに消去されません。スタックを共有するために、フラッシュ内の指定されたメモリ位置に配置される定数関数構造を作成しました。私が使用しているコンパイラは、Freescale の Embedded PowerPC ツールです。私のブートコードでは、次のようになります。
イーサネット.h
typedef Ethernet_Struct = {
int (*enet_init) (void);
void (*enet_release) (void);
int (*enet_bind)(...);
int (*enet_recvfrom)(...);
}
extern const Ethernet_Struct enet;
イーサネット.c
const Ethernet_Struct enet = {
enet_init,
enet_release,
enet_bind,
enet_recvfrom
}
次に、リンカがこのオブジェクト ファイルを 0x1ffc0 (フラッシュ) に配置すると、マップ ファイルですべてが適切に表示されます。この場所を参照するリンカー シンボルは _ENET_STRUCT_ です。私のアプリケーションでは、これを行います:
app.c
#include "ethernet.h"
extern uint32 _ENET_STRUCT_;
const Ethernet_Struct *enet = (Ethernet_Struct *) &_ENET_STRUCT_;
void main() {
enet->enet_init(); /* In the assembly, it's trying to
branch to a location that is not even in flash */
}
enet はブート コードと同じように .rodata に配置されると思いますが、実際には .sdata に配置されます。sdata セクションを ROM から RAM にコピーしようとすると、enet は 0x1ffc0 を指しています。デバッガーは正しい場所も表示します。しかし、アセンブリは、フラッシュや RAM 以外の場所に分岐しようとしていることを示しています。ここで何が起こっているかについての私の最善の推測は、そのアドレスを取得するためにリンカーに依存しているため、コンパイラは enet がどこを指しているのかわからないということです。
これは実際に機能しますが、アドレスに明示的な値を指定するのは好きではありません。
#define enet ((Ethernet_Struct *) 0x1ffc0)
では、パーティション間のインターフェイスを作成する正しい方法は何ですか?