【问题标题】:Function Pointer or Jump table函数指针或跳转表
【发布时间】:2015-10-01 07:04:39
【问题描述】:

在问这个问题之前,让我先提供一些背景:

我正在阅读关于Autosar 架构的technical article,它建议了应用层软件组件的即插即用方法。基本上这篇文章建议您可以将内存划分为单独的组件,并仅对那些已修改的组件而不是整个软件映像进行编程 /flash。这将在访问经销商期间节省一些重新编程时间。现在,由于正在重新编程的函数的地址可能会发生变化,当这些修改后的函数被位于另一个分区(内存部分)中的函数调用时,这将导致问题。文章通过使用位于固定地址并包含更新函数的地址的跳转/间接表来提出此方法的解决方案。

现在让我进入问题部分:

我不是从Autosar 架构考虑这个问题,而是从嵌入式工程师的角度考虑这个问题,并认为虽然这种方法可行,但它会增加吞吐量。我认为可以使用的另一个选项可能是函数指针。但是后来我认为在正常情况下,链接器将函数符号名称替换为其实际地址,因此函数 A(位于未更改分区中)被初始化为函数 B(位于更新分区和可能在不同的地址)将不起作用。

这终于让我想到了我的最后一个问题:

  1. 函数指针的方法会起作用吗? (我认为它可能不会。)
  2. 如果上述问题的答案是否定的,我是否仍然可以使用函数指针方法,例如将所有函数指针保持在固定地址并使用脚本和映射文件修补实际地址。

感谢大家耐心解答这么长的问题。我希望我能提出一个小问题。

【问题讨论】:

  • 您正在阅读的文章是否可以公开访问?如果是这样,请在问题中提供它的 URL。
  • 我已将 URL 添加到问题中。下次请自己做——谢谢。

标签: c linker embedded function-pointers jump-table


【解决方案1】:

我认为指向函数的指针会起作用,但它与跳转表并没有什么不同。您仍然需要一个固定地址的表,您可以在其中找到最终函数的地址。您必须初始化指向函数的指针,链接器对此无济于事。唯一的好处是在执行时:直接调用函数而不是间接跳转。

在下面的代码中,我假设一个组件位于固定地址 0xf800,并且该组件的函数地址存储在此内存的开头:

// Functions addresses table at 0xf800
// 0xf800 stores the @ of func1 of the component
// 0xf804 @func2
// 0xf808 @func3
// etc.

// Initialization of the pointers to function
// Here each function has a int as parameter and returns an int 
int (*func1)(int) = *((int(**)(int))(0xf800));
int (*func2)(int) = *((int(**)(int))(0xf804));
int (*func3)(int) = *((int(**)(int))(0xf808));

// Use of a pointer to call a function of the component
int result = func1(1234);

【讨论】:

  • 谢谢乔尔。这与我的想法一致。我的解决方案是按照我们今天的方式将所有组件编译在一起,然后使用脚本和映射文件在固定位置修补正确的函数地址。这样我也节省了间接成本。再次感谢您的调查。
猜你喜欢
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2017-12-28
  • 1970-01-01
  • 2015-11-03
  • 2017-02-24
  • 2016-06-03
相关资源
最近更新 更多