2

我正在开发一个带有裸机环境的 cortex-m3 CPU 项目。由于软件升级需要,CPU 上的可执行映像可能位于闪存中的两个地址之一,这会带来问题。映像的起始地址仅在加载时才知道,而在静态链接期间不知道。我不太确定,但我认为这并不真正符合动态加载的条件,但我在这里真的可能被误认为,因为我不是这方面的专家。有没有办法编译和链接图像,因为它的基地址只能在加载时给出,因为没有操作系统也没有动态加载器?

4

2 回答 2

2

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

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

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

您可能会发现这个其他 SO 问题(“尝试在 cortex-m3 上加载与位置无关的代码”)也很有帮助。

于 2011-06-13T19:23:53.273 回答
0

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

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

  • 需要一个小的引导加载程序 - 它被构建并链接为在复位时获得 CPU 控制权的程序
  • 主程序映像实际上构建了两次 - 每个可能的位置一次。注意:两个可能的加载位置是固定的,并且由引导加载程序知道。
  • 程序映像的开头有一个小数据结构,其中包含对引导加载程序很重要的几位信息。其中有程序的入口地址和程序镜像的校验和

引导加载程序检查固定的、众所周知的位置以校验两个可能的图像。

  • 如果它没有找到有效的图像,它会简单地循环(看门狗会重置设备,但这并不重要——在加载有效的主程序之前它是一块砖)
  • 如果它只找到一个有效的图像,那就是它跳转到的入口点。
  • 如果它发现两个图像都有效,它会使用数据结构中的其他信息来确定要控制哪一个(版本信息,最后一次已知的好,无论您的策略是什么)。

关键是引导加载程序必须简单而愚蠢。它不容易升级,所以你希望它足够愚蠢以至于它不能有错误。

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

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

于 2011-06-14T18:49:39.560 回答