用函数 B 覆盖弱函数 A
override a weak function A with a function B
对于嵌入式设备,我有一个包含一个数组的文件,该数组带有存储中断处理程序的函数指针,这样定义(我无法修改它):
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();
}
我想知道有没有解决方案可以通过blinkLed
直接覆盖弱函数ISR78
,ie存储blinkLed
的地址在__vector_table
不修改或重命名函数?
编辑:
我实际上使用的是 GNU gcc 4.9.3 和关联的链接器 (GNU ld 2.24.0)。我可以修改与项目关联的 main.c
和 Makefile。
我看到实现你想要做的事情的唯一方法是用 ISR78
符号修补包含 blink
符号的目标文件的符号 table。
objcopy [...] --redefine-sym blink=ISR78
应该这样做。然后链接器应该自动将前 blink
的地址插入到向量 table 中。显然,你的 blink
符号在那之后就消失了,不应该从其他地方调用。
但是,我会认为这是一个 hack。
如果 _vector_table
是全局可访问的并且在 writable 内存中(不假设,这可能太简单了......),你可以简单地通过 [=17 从你自己的代码中修补它=]
_vector_table [0x78] = blink;
在运行时。
tl;dr:您已经有了一个可行的解决方案,这似乎是首先使用弱符号明确支持和鼓励的解决方案。您期望从不同的解决方案中得到什么改进?
链接器符号是按名称查找的,因此使用预期名称的唯一替代方法是:
- tofro建议直接修改link步骤
- 自己修改函数指针table
首先使 ISR78 成为弱符号的全部意义在于允许完全覆盖(按符号名称)您已经使用过。
我看不出任何修改中断向量 table 的方式 比直接使用预期的函数名称更好,即使这是可能的。
对于嵌入式设备,我有一个包含一个数组的文件,该数组带有存储中断处理程序的函数指针,这样定义(我无法修改它):
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();
}
我想知道有没有解决方案可以通过blinkLed
直接覆盖弱函数ISR78
,ie存储blinkLed
的地址在__vector_table
不修改或重命名函数?
编辑:
我实际上使用的是 GNU gcc 4.9.3 和关联的链接器 (GNU ld 2.24.0)。我可以修改与项目关联的 main.c
和 Makefile。
我看到实现你想要做的事情的唯一方法是用 ISR78
符号修补包含 blink
符号的目标文件的符号 table。
objcopy [...] --redefine-sym blink=ISR78
应该这样做。然后链接器应该自动将前 blink
的地址插入到向量 table 中。显然,你的 blink
符号在那之后就消失了,不应该从其他地方调用。
但是,我会认为这是一个 hack。
如果 _vector_table
是全局可访问的并且在 writable 内存中(不假设,这可能太简单了......),你可以简单地通过 [=17 从你自己的代码中修补它=]
_vector_table [0x78] = blink;
在运行时。
tl;dr:您已经有了一个可行的解决方案,这似乎是首先使用弱符号明确支持和鼓励的解决方案。您期望从不同的解决方案中得到什么改进?
链接器符号是按名称查找的,因此使用预期名称的唯一替代方法是:
- tofro建议直接修改link步骤
- 自己修改函数指针table
首先使 ISR78 成为弱符号的全部意义在于允许完全覆盖(按符号名称)您已经使用过。
我看不出任何修改中断向量 table 的方式 比直接使用预期的函数名称更好,即使这是可能的。