功能指针或跳转表

时间:2015-07-13 05:52:48

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

在提出问题之前,请提供一些背景信息:

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

现在让我谈谈问题部分:

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

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

  1. 函数指针的方法是否有效? (我想可能不会。)
  2. 如果上述问题的答案为否,我仍然可以使用函数指针方法,将所有函数指针保持在固定地址,并使用脚本和映射文件来修补实际地址。
  3. 我感谢所有耐心等待这么长时间问题的人。我希望我能提出一个小问题。

1 个答案:

答案 0 :(得分: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);