Embedded 加载时间基址cortex-m3裸机

Embedded 加载时间基址cortex-m3裸机,embedded,arm,dynamic-loading,cortex-m3,gnu-toolchain,Embedded,Arm,Dynamic Loading,Cortex M3,Gnu Toolchain,我正在一个cortex-m3 CPU的裸机环境下工作。 由于软件升级需要,CPU上的可执行映像可能位于闪存中的两个地址中的一个,这会出现问题。映像的起始地址仅在加载时已知,而在静态链接期间未知。 我不太确定,但我认为这实际上不符合动态加载的条件,但我在这里可能真的弄错了,因为我不是这方面的专家。 在没有操作系统和动态加载程序的情况下,是否有一种方法可以编译和链接映像,使其基址只能在加载时给出?对于像您这样的裸机嵌入式系统,这是通过将代码编译/链接为可重定位代码(也称为可重定位代码)来实现的 如何

我正在一个cortex-m3 CPU的裸机环境下工作。 由于软件升级需要,CPU上的可执行映像可能位于闪存中的两个地址中的一个,这会出现问题。映像的起始地址仅在加载时已知,而在静态链接期间未知。 我不太确定,但我认为这实际上不符合动态加载的条件,但我在这里可能真的弄错了,因为我不是这方面的专家。
在没有操作系统和动态加载程序的情况下,是否有一种方法可以编译和链接映像,使其基址只能在加载时给出?

对于像您这样的裸机嵌入式系统,这是通过将代码编译/链接为可重定位代码(也称为可重定位代码)来实现的

如何实现这一点受处理器的影响,而实际的方法是由您的开发工具集实现的,因此您需要查阅交叉开发工具的文档。通常是一组编译器和链接器选项(包括你的链接器命令脚本,如果你有)来决定事情的布局以及使用什么寄存器来访问它们

当您使用支持MMU的平台(处理器和操作系统)(抱歉,不在CM3上)时,事情会变得简单一些,这样代码就可以位于物理内存中的任何位置,但通过MMU,其逻辑地址空间可能会有所不同。因此,在链接时,代码和数据的地址可以固定,然后在加载时,通过MMU设置逻辑地址空间,程序也就不那么明智了


您可能会发现另一个SO问题()也很有帮助

您需要某种方法让设备确定何时重置,它应该从两个可能的位置中的哪一个开始执行。但通常,裸机设备只有一个复位时运行的起始位置(一些控制器可以根据设备上某些管脚的逻辑级别从两个或更多入口点中进行选择)

我们也有类似的要求,并制定了以下方案:

  • 一个小的引导程序是必需的-它是建立和链接的程序,获得控制CPU复位
  • 主程序映像实际上是构建两次的,每个可能的位置一次。注意:两个可能的加载位置是固定的,引导加载程序知道这两个位置
  • 在程序映像的开头有一个小数据结构,其中包含对引导加载程序非常重要的几位信息。其中包括程序的入口点地址和程序映像的校验和
引导加载程序检查固定的已知位置,以对两个可能的映像进行校验和

  • 如果没有找到有效的图像,它只会循环(看门狗会重置设备,但这并不重要——在加载有效的主程序之前,它是一块砖块)
  • 如果它只找到一个有效的图像,那就是它跳转到的入口点
  • 如果它发现两个映像都有效,它将使用数据结构中的其他信息来确定将控制权交给哪一个(版本信息、最后一个已知的商品,无论您的策略是什么)
关键是引导加载程序必须简单而愚蠢。它不容易升级,所以你希望它足够愚蠢,不会有bug

现在,设备可以在运行时升级,方法是将图像闪烁到非运行位置(我们的Cortex-M3设备允许这样做-如果LPC1758不允许这样做,那么您必须让从RAM运行的设备执行闪存更新)。重置,引导加载程序将拾取新刷新的图像


该系统需要一点前期工作,以使引导加载程序运行并稳定,但一旦其工作,更新将100%可靠(如果新闪存未完成,则旧映像是唯一进行校验和的映像,因此它将在下次重置时运行-无砖块)。主要的缺点是——这是一个很大的缺点——你基本上失去了主程序的一半闪存地址空间,因为闪存必须能够保存两个竞争图像。

好吧,尝试了参考链接中的说明,我的工具链(我想)甚至不支持PIC/PIE选项,我想是因为newlib的编译方式。我在LPC1758上使用NXP LPCXpresso BTW。如果您不需要newlib或gcclib,您可能会有更大的灵活性,如果不需要,则根据您的应用程序大小,您基于闪存的启动代码可以简单地将二进制文件复制到ram并从那里分支/运行。你为固定的ram地址编译你的应用程序,启动/复制代码很简单,一些汇编程序包在二进制文件中(可以是PIC,因为你是手工做的)。这是一个带有分支的ldm/stm循环。这个解决方案确实很容易实现,而且可以正常工作,但我担心我们的应用程序二进制映像比RAM大小大(64KB,其中一半用于AHB或类似的东西)。Boaz我喜欢你的回答,但我想知道如何从应用程序构建环境管理对操作系统端的引用。例如,OS端有一些我想从应用端访问的变量。这两个东西怎么能单独构建并在运行时连接呢?嗨,Michael,这实际上是我们目前正在做的事情,我希望找到一个更像第一个答案中提出的解决方案。不过,非常感谢您提供了信息丰富的答案。