加载时间基址 cortex-m3 裸机

发布于 2024-11-14 21:03:38 字数 207 浏览 2 评论 0原文

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

I'm working on a project on a cortex-m3 CPU with bare-metal environment.
Due to software upgrade needs the executable image on the CPU can be in one of two addresses in the flash memory which presents a problem. The start address of the image is known only at load time and not during static-linkage.
I'm not too sure but I think this doesn't really qualify as dynamic loading but I could really be mistaken here as I'm no expert on this.
Is there a way to compile and link the image in a way it's base address can be given only at load time given there is no OS and no dynamic loader?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南薇 2024-11-21 21:03:38

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

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

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

您可能会发现另一个SO问题(“尝试加载位置独立cortex-m3 上的代码”)也很有帮助。

For bare-metal embedded systems like yours, this is accomplished by compiling/linking your code as relocatable code, also known as Position Independent Code.

How this is accomplished is influenced by the processor, and the actual approach is implemented by your development toolset, so you'll want to consult with the documentation for your cross-development tools. It is usually a set of compiler & linker options (incl. your linker command script, if you have one) that determine how things are laid out & what registers are used to access them.

Things become a little easier when you're working with a platform (processor & OS) that supports an MMU (not on the CM3, sorry) - then the code can be located anywhere in physical memory, but via the MMU, its logical address space can be different. Thus, at link time, addresses for code & data can be fixed, and then at load time, the logical address space is set up via the MMU, and the program is none the wiser.

You might find this other SO question ("Trying to load position independent code on cortex-m3") helpful as well.

岁月静好 2024-11-21 21:03:38

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

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

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

引导加载程序检查固定的众所周知的位置,以对两个可能的映像进行校验和。

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

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

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

该系统需要一些前期工作才能使引导加载程序运行并坚如磐石,但一旦工作,更新就是 100% 可靠的(如果新闪存未完成,则旧映像是唯一进行校验和的映像,因此它将在下次重置时运行 - 无砖块)。主要缺点(而且是一个很大的缺点)是,您实际上会失去主程序的一半闪存地址空间,因为闪存必须能够容纳两个竞争的图像。

You need some way for the device to determine when it is reset which of two possible locations it should start executing from. But generally a bare-metal device has only a single starting location it runs from when it's reset (some controllers can select from two or maybe more entry points based on the logic level of some pins on the device).

We had a similar requirement, and worked out the following scheme:

  • a small bootloader program is required - it's built and linked to be the program that gains control of the CPU at reset
  • the main program image is actually built twice - once for each possible location. Note: the two possible loading locations are fixed and known by the bootloader.
  • there's a small data structure at the start of the program image that contains several bits of information important to the bootloader. Among them are the entry point address of the program and a checksum of the program image

The bootloader examines the fixed, well-known locations to checksum the two possible images.

  • if it finds no valid images, it simply loops (the watchdog will reset the device, but that doesn't really matter - it's a brick until a valid main program is loaded)
  • if it finds only one valid image, that's the entry point that it jumps to.
  • if it finds both images are valid it uses other information in the data structure to determine which one to give control to (version information, last known good, whatever your policy might be).

The key to this is that the bootloader must be simple and stupid. It's not easily upgradeable, so you want it to be stupid enough that it can't have bugs.

Now the device can be upgraded while it's running by flashing the image to the non-running location (the Cortex-M3 device we have allows this - if the LPC1758 doesn't allow this, then you have to have something that runs from RAM perform the flash update). Reset, and the bootloader picks up the newly flashed image.

The system requires a little up-front work to get the bootloader running and rock-solid, but once it's working updates are 100% reliable (if the new flash doesn't complete, the old image is the only one that checksums, so it'll run at next reset - no bricks). The main disadvantage - and it's a big one - is that you essentially lose half your flash address space for the main program since the flash has to be able to hold two compete images.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文