函数指针或跳转表



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

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

现在让我回到问题部分:

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

这就引出了我最后一个问题:

  1. 函数指针的方法会工作吗?(我认为可能不会)
  2. 如果上面的问题的答案是否定的,我仍然可以使用函数指针的方法,说保持所有的函数指针在固定的地址和使用脚本和映射文件来修补实际的地址。
我感谢你们所有人有足够的耐心来回答这么长的问题。我希望我能提出一个小一点的问题。

我认为指向函数的指针会起作用,但它与跳转表并没有什么不同。你仍然需要一个固定地址的表,在那里你可以找到final函数的地址。你必须初始化指向函数的指针,链接器对此没有帮助。唯一的好处是在执行时:函数被直接调用,而不是通过间接跳转。

在下面的代码中,我假设组件位于固定地址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);

最新更新