我有一个TCP / IP堆栈,我需要在启动分区和应用程序分区之间共享。堆栈在引导代码中初始化,引导和应用程序都使用堆栈。两个分区都位于同一个闪存模块中,但是在不同的闪存部分中,因此它们不会相互擦除。为了共享堆栈,我创建了一个常量函数结构,放置在flash中的指定内存位置。我正在使用的编译器是飞思卡尔的嵌入式PowerPC工具。在我的启动代码中,它看起来像这样:
ethernet.h
typedef Ethernet_Struct = {
int (*enet_init) (void);
void (*enet_release) (void);
int (*enet_bind)(...);
int (*enet_recvfrom)(...);
}
extern const Ethernet_Struct enet;
ethernet.c
const Ethernet_Struct enet = {
enet_init,
enet_release,
enet_bind,
enet_recvfrom
}
然后链接器将此目标文件放在0x1ffc0(flash),并且我的地图文件中的所有内容都很好。引用此位置的链接器符号是_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)
那么,在分区之间创建接口的正确方法是什么?