4

对于嵌入式设备,我有一个文件,其中包含一个带有存储中断处理程序的函数指针的数组,像这样定义(我不能修改它):

typedef void (*const ISRFunction)(void);

__attribute__((weak)) void ISR0(void){ for(;;); }
__attribute__((weak)) void ISR1(void){ for(;;); }
...
__attribute__((weak)) void ISR78(void){ for(;;); }
...

ISRFunction __vector_table[0x79] = 
{
    (ISRFunction)&ISR0,
    (ISRFunction)&ISR1,
    ...
    (ISRFunction)&ISR78,
    ...
}

我有第二个文件,它定义了一些我无法修改的功能。这个文件就像:

void blinkLed(void)
{ ... }

最后,我有一个主源文件,包含main设备的功能和配置。在中断 78 上,我想闪烁 LED。所以我写了一个这样的强大函数ISR78

void ISR78(void)
{
    blinkLed();
}

我想知道是否有解决方案ISR78直接覆盖弱函数blinkLed存储blinkLed内部地址__vector_table而不修改它或重命名函数?


编辑:

我实际上使用 GNU gcc 4.9.3 和相关的链接器(GNU ld 2.24.0)。我可以修改main.c与项目关联的 Makefile。

4

2 回答 2

1

我看到实现您想要做的唯一方法是用符号修补包含符号的目标文件的符号blinkISR78

objcopy [...] --redefine-sym 闪烁=ISR78

应该这样做。然后链接器应该自动将前者的地址插入blink向量表中。显然,您的blink符号在那之后就消失了,不应该从其他地方调用。

但是,我会认为这是一种 hack。

如果_vector_table可以全局访问并且在可写内存中(不假设,这可能太简单了......),你可以简单地从你自己的代码中修补它

_vector_table [0x78] = blink;

在运行时。

于 2016-08-01T12:25:17.987 回答
1

tl; dr:您已经有了一个可行的解决方案,这似乎是首先使用弱符号明确支持和鼓励的解决方案。您期望从不同的解决方案中获得什么改进?


链接器符号按名称查找,因此使用预期名称的唯一替代方法是:

  1. tofro 建议直接修改链接步骤
  2. 自己修改函数指针表

首先使 ISR78 成为弱符号的全部意义在于允许您已经使用过的覆盖(按符号名称)。

我看不出任何修改中断向量表的方法比直接使用预期的函数名更好,即使它是可能的。

于 2016-08-01T12:33:52.487 回答