是否可以一次一个地运行存储在Flash(微控制器)中的2个不同的C程序(即2个main())?
我有一个引导加载程序代码,它是一个单独的程序,位于ROM的单独受保护部分。然后我有我的应用程序,它位于单独的ROM部分。虽然,驻留在内存中不是问题,但链接器将如何解释这一点?如何在两个程序之间切换。这可能吗?
例如: 一旦我完成了bootloader,我可以跳转到Application函数,但链接器将如何知道这个函数?
添加,我使用的是飞思卡尔HCS08系列,IDE是Codewarrior。
此外,以下是一系列步骤: 我在ROM中加载了Bootloader代码。然后,需要此引导加载程序代码来加载我的应用程序代码。然后我的应用程序代码应该接管。
Bootloader代码: 程序应用区ROM 启动应用程序
申请代码: 检查是否运行Bootloader代码或应用程序本身。
答案 0 :(得分:1)
Main只是一个功能。您可以重命名它并写另一个调用其中任何一个的主。
如果您不想在源代码中重命名main,可以通过define或编译器键来修改其名称:
cc -Dmain=main1 ...
(对于第一个程序)和
cc -Dmain=main2 ...
(第二次)。选择器主:
int main(void) {
if(x) return main1();
else return main2();
}
然后将所有链接连接起来并下载到您的控制器。
但是ISR存在问题:你不能将两个例程分配给单个irq向量。如果向量硬编码到某个闪存位置(就像在大多数8位控制器中一样),则无法切换ISR。您必须编写ISR包装器,识别运行的程序并调用适当的ISR。
<强> UPD 强> 第二个问题是来自第一和第二程序的静态链接变量将同时在RAM中,而只使用其中一组。这可能会过早地耗尽RAM(少量通常存在于微控制器中)。
<强> UPD2 强> 哦,现在我真的明白了。如果要单独链接和下载它们,则应该处理链接器映射。在这种情况下,相同的符号名称(例如许多主要的)不是问题。在链接器映射中,您应该定义已知的入口点[将其设置为绝对地址],应用程序代码从该入口点开始。应该从此地址链接启动代码(通常是汇编代码)。从选择器您应该决定并直接跳转到定义的位置。 (如果您的应用程序也是选择器,请仅对引导加载程序执行此操作。)
链接器提供的入口点可以通过程序作为外部函数访问:
int app2_start(void);
{
.... /* condition check */
app2_start(); /* this symbol defined in linker map, not in any source */
}
但这不是它的main()的地址,因为C RTL在main()可以启动之前做了很多初始化(堆栈,初始化变量,堆,IO等)。
如果引导程序运行自身或应用程序,引导加载程序会有更常见的方法,因为如果应用程序代码失败,boodloader可能无法访问。
答案 1 :(得分:0)
我看到这样做的方法是将入口点粘贴到应用程序的标题中。然后让引导加载程序将该入口点拉出并使用适当的内联汇编指令跳转到该入口点。您可能需要一个链接描述文件来从应用程序中获取入口点。 Gnu ld使用ENTRY。