2

我正在研究Cortex-M3。我想在现有固件映像中添加一个功能(或 ISR)而不更新整个程序。我可以在没有 main 的情况下编译和构建一个函数并写入闪存吗?如果我知道这个函数的写入地址,我可以使用函数指针调用这个函数吗?

我们有单线程代码,没有操作系统。根本问题是在这种情况下我们将如何创建一个安装和使用应用程序的环境。

4

2 回答 2

0

是的你可以。

在确定您知道如何解决此问题之前,您需要了解 3 个文件:

  1. SAM3N4C 启动代码
  2. DeviceVectors 定义
  3. SAM3N4C 链接器内存区域定义
  4. SAM3N4C 链接描述文件

我已经给了你SAM3N4C芯片的链接,因为我很熟悉它。可以制作代码以适合您正在使用的芯片。

要使其满足您的要求,您将需要一个向量表,其中包含指向您的函数的指针。您需要将此向量表放在一个已知地址,然后使用它来获取函数指针。您的函数将紧跟在该向量表之后的内存中。

简要说明:

看来您仍然不熟悉 Cortex-M3 上的工作原理,所以我将尝试解释一下。

main并不特别。它只是一个函数,甚至不是第一个执行的东西。在 Cortex-M3 上运行的第一个函数是复位向量中断服务程序。然后,此函数设置您的所有内存,然后调用 main(请参阅SAM3N4C 启动代码)。

在 Cortex-M3 上,有一个指向此特殊功能的指针,位于距内存开头 (0x00000004) 的已知偏移量处,这就是您的硬件用于启动/启动的内容。SAM3N4C 启动代码中的Reset_Handler()函数位于该地址。这是在结构中完成的,您可以在SAM3N4C 启动代码中给出的代码中看到该结构被初始化。该结构包含所有函数指针,并且对于要位于距内存开头的 0x00000004 偏移量的复位向量,需要将其放置在内存的最开头。这是通过使用标志将.vectors部分放置来完成的(请参阅GNU 属性语法)。然后将其用于DeviceVectors exception_tableexception_table__attribute__ ((section(".vectors")))exception_tableSAM3N4C 链接器脚本,其中包括 SAM3N4C 链接器内存区域定义中给出的内存区域定义,将其放置在内存的最开头(使用首先KEEP(*(.vectors .vectors.*))放入内存的行)。

我建议调查您现有的链接器脚本以了解它们是如何工作的,因为它们会为您提供有关如何执行此操作的线索。阅读有关GNU 链接器的更多信息将帮助您。

此外,在我看来,你所追求的解决方案会复制这种行为,但你会使用更小的“向量表”,因为你只需要一个函数......

于 2013-09-23T01:43:34.457 回答
0

如果您使用“位置无关代码”编译代码,那么您的函数可以重新定位在 ROM(闪存)或 RAM 中的任何位置。

编写重定位在内存中的代码仍然不是一件容易的事,您应该确保了解 ARM 架构,至少不要害怕 ARM 机器指令集。诀窍是首先了解这在指令级是如何发生的,然后尝试用 C 做同样的事情。当然,有一些复杂性。在main运行之前,初始化程序中有幕后工作,设置零和非零初始化变量。这取决于您的编译器实际如何进行。运行一个虚拟程序很有用,并你到达main.

请参阅此相关问题:尝试在 cortex-m3 上加载与位置无关的代码

于 2013-09-23T03:43:23.573 回答