首先我要说的是我开发基于 Cortex m4 的嵌入式设备应用程序。
我有引导加载程序和主应用程序常用的功能。现在我为引导加载程序和应用程序编译源文件两次。但我的双组 dfu 空间不足,我只想在 ROM 中使用这些功能一次。知道我怎样才能实现这个目标吗?
编辑:
在某些情况下使用函数指针可能存在危险,请检查我的问题 -使用指针函数 - 1 台设备上的 2 个独立应用程序
小智 5
这只是部分答案,假设您可以使用相同的地址空间从主代码跳转到引导加载程序。然后,一种常见的技术是提供“引导加载程序 API”作为函数指针表。
举例来说,您的引导加载程序中有以下功能:
static int do_something(void)
{
return 42;
}
static int do_something_else(int arg)
{
return arg+5;
}
Run Code Online (Sandbox Code Playgroud)
然后您可以在标头中声明您的 API,如下所示:
struct bootloaderApi
{
int (*do_something)(void);
int (*do_something_else)(int arg);
};
Run Code Online (Sandbox Code Playgroud)
在引导加载程序的实现中,您可以在其自己的部分中定义此表:
// this is GCC syntax, use whatever your compiler provides to specify the section
struct bootloaderApi api __attribute__((section("API"))) = {
do_something,
do_something_else
};
Run Code Online (Sandbox Code Playgroud)
然后,在构建引导加载程序时,请确保您的部分放置在合适的固定地址。例如,当使用 GNU 链接器时,您的链接器脚本中可能会包含以下内容:
SECTIONS {
// standard sections, e.g.:
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) *(COMMON) }
// your API table:
.API 0x10000 : { *(.API) }
}
Run Code Online (Sandbox Code Playgroud)
现在假设您的 API 表将放置在0x10000。然后您可以执行以下操作从主代码访问 API:
struct bootloaderApi *api = (struct bootloaderApi *)0x10000;
api->do_something();
Run Code Online (Sandbox Code Playgroud)
所有这些只是一个草图,旨在让您了解如何以合理的方式做到这一点。这在很大程度上取决于您的目标平台和您正在使用的工具链。