将代码添加到现有固件

时间:2013-09-21 12:57:54

标签: c embedded arm bare-metal

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

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

2 个答案:

答案 0 :(得分:0)

是的,你可以。

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

  1. The SAM3N4C Startup Code
  2. The DeviceVectors definition
  3. The SAM3N4C Linker Memory Region Definitions
  4. The SAM3N4C Linker Script
  5. 我已经为您提供了SAM3N4C芯片的链接,因为我对它很熟悉。代码可以适合您正在使用的芯片。

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

    简要说明:

    您似乎还不熟悉Cortex-M3的工作方式,所以我会尝试解释一下。

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

    在Cortex-M3上,有一个指向此特殊函数的指针,该指针位于距内存开头(0x00000004)的已知偏移处,这是您的硬件用于启动/启动的指针。来自The SAM3N4C Startup CodeReset_Handler()功能位于该地址。这是在DeviceVectors exception_table结构中完成的,您可以在The SAM3N4C Startup Code中给出的代码中初始化该结构。该结构包含所有函数指针,并且复位向量位于距存储器起始位置0x00000004的偏移处,exception_table需要放置在内存的最开始处。这是通过使用__attribute__ ((section(".vectors")))标记将exception_table放入 .vectors 部分来完成的(请参阅The GNU attribute syntax)。然后在The SAM3N4C Linker Script中使用它,其中包括The SAM3N4C Linker Memory Region Definitions中给出的内存区域定义,将其放在内存的最开头(使用KEEP(*(.vectors .vectors.*))行,将其放入内存<强>第一)。

    我建议您调查现有的链接描述文件,看它们是如何工作的,因为它们会为您提供有关如何执行此操作的线索。阅读更多关于the GNU linker的信息将对您有所帮助。

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

答案 1 :(得分:0)

如果使用“位置无关代码”编译代码,则可以将函数重定位到ROM(Flash)或RAM中的任何位置。

编写重新定位在内存中的代码仍然不是一件容易的事情,您应该确保理解ARM体系结构,至少不要害怕ARM机器指令集。诀窍是首先要了解在指令级别如何发生这种情况,然后尝试用C做同样的事情。当然,有并发症。在main运行之前,初始化过程中有幕后工作,它们设置零和非零初始化变量。这取决于你的编译器实际上如何进行。运行虚拟程序非常有用,并逐步完成所有执行 BEFORE 到达main

请参阅此相关问题:Trying to load position independent code on cortex-m3