【问题标题】:Two different programs in FlashFlash 中的两个不同程序
【发布时间】:2010-11-11 23:23:40
【问题描述】:

是否可以一次运行 2 个不同的 C 程序(即 2 个 main()),存储在 Flash(微控制器)中?

我有一个引导加载程序代码,它是一个单独的程序,位于 ROM 的单独受保护部分中。然后我有我的应用程序,它位于单独的 ROM 部分。虽然,驻留在内存中不是问题,但链接器将如何解释这一点?如何在 2 个程序之间切换。这可能吗?

例如: 一旦我完成了引导加载程序,我可以让它跳转到应用程序函数,但是链接器如何知道这个函数呢?

补充一下,我用的是飞思卡尔HCS08系列,IDE是Codewarrior。

此外,以下是步骤顺序: 我在 ROM 中加载了一个引导加载程序代码。然后需要这个引导加载程序代码来加载我的应用程序代码。然后我的应用程序代码应该会接管。

引导加载程序代码: 程序应用区ROM 启动应用程序

申请代码: 检查是否运行引导加载程序代码或应用程序本身。

【问题讨论】:

  • 我认为答案,如果可能的话,将是微控制器特定的。提供您的目标芯片,您将有更好的机会得到答案。

标签: c linker microcontroller


【解决方案1】:

Main 只是一个函数。您可以重命名它并编写另一个调用它们中的任何一个的 main。

如果您不想在源代码中重命名 main,您可以通过定义或编译器键来修改其名称:

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(微控制器中通常存在少量 RAM)。

UPD2 哦,现在我真的明白了。如果您想单独链接和下载它们,您应该处理链接器映射。在这种情况下,相同的符号名称(例如许多 main 的)不是问题。在链接器映射中,您应该定义已知的入口点 [将其设置为绝对地址],任一应用程序代码都从该入口点开始。启动代码(通常是汇编代码)应该从这个地址链接。您应该从选择器中决定并直接跳转到定义的位置。 (如果您的应用也是选择器,则仅为引导加载程序执行此操作)。

链接器提供的入口点可以作为外部函数被程序访问:

int app2_start(void);

{
   .... /* condition check */
   app2_start(); /* this symbol defined in linker map, not in any source */
}

但这不是 main() 的地址,因为 C RTL 确实在 main() 可以启动之前进行了许多初始化(堆栈、初始化变量、堆、IO 等)。

引导加载程序有更常见的决定方式,它应该运行自己还是应用程序,因为如果应用程序代码失败,引导加载程序可能变得无法访问。

【讨论】:

  • 感谢您的意见。好吧,我认为 Vectors 不会有问题,因为我将它们保存在引导加载程序代码和应用程​​序代码的相同位置。并且一次将运行应用程序代码或引导加载程序代码。那么,ISR 是安全的吗??
  • 不,ISR 在这里并不安全。这种方法使其本质上是一个具有两个功能的程序。
  • ISR 会像您编写它们一样安全。我只是说,对于单个向量,您可能不能有两个不同的 ISR。两个程序是否相同,这不是问题。
  • @Nathon,你能说清楚,什么是程序的“一个单元”吗?我不知道如何确定单个十六进制文件是一个或多个程序。
  • 两个十六进制文件是两个程序。一种看待它的方法是作为编译单元。在您的示例中,有三个编译单元:程序 1、程序 2 和选择器 main。此外,它不是一个单独的十六进制文件。这就是重点。
【解决方案2】:

我看到的做法是将入口点粘贴到应用程序的标头中。然后让引导加载程序将该入口点拉出并使用适当的内联汇编指令跳转到它。您可能需要一个链接描述文件来从应用程序中获取入口点本身。 Gnu ld 使用ENTRY

【讨论】:

  • 您能否进一步解释一下,因为我有两个 _Entrypoints,一个用于引导加载程序,另一个用于应用程序。
  • @punit:这两个程序是独立链接的,第二个程序的入口点在第一个读取的标题中。
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
相关资源
最近更新 更多