GCC在翻译单元之外给函数起别名——也就是说,这真的是适合这个任务的正确工具吗?

14
我正在使用FreeRTOS在STM32(Cortex-M3)上工作,并使用ST的CMSIS库来引导一切。
CMSIS库在启动的".s"文件中定义了弱符号"SVC_Handler"。为了将您的ISR放入中断向量表中,必须在某个地方覆盖它。FreeRTOS定义了"vPortSVCHandler",这是我想要处理SVC中断的ISR。
我希望使用我的应用程序代码将两者"粘合"在一起(即不修改FreeRTOS或CMSIS源代码)。我认为别名是完成此任务的正确工具,所以我尝试了以下方法(在一个单独的源文件main.c中):
void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler")));

这导致出现错误:'SVC_Handler'别名为未定义的符号 'vPortSVCHandler'。
事实证明,根据GCC文档http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html,为了使用alias属性,你不能将一个符号别名化到翻译单元之外。所以我想尝试在main.c中使用extern来引用该符号。
extern void vPortSVCHandler( void ) __attribute__ (( naked ));
void SVC_Handler(void) __attribute__ ((alias ("vPortSVCHandler")));

这会产生相同的错误。有什么建议吗?
我真的不想修改任何一个库。我知道我可以编写一个名为SVC_Handler的函数,只需调用vPortSVCHandler,但这可能会给ISR增加不必要的开销(可能取决于优化设置)。注意:FreeRTOS示例通过自定义启动文件实现了这一点。我正在寻找一种从C或我的链接脚本中实现这一点的方法。
编译器版本:gcc version 4.5.2 (Sourcery G++ Lite 2011.03-42) 目标:arm-none-eabi
4个回答

10

您可以通过链接脚本或通过向链接器传递适当的选项来完成此操作,例如对于ld,使用--defsym=SVC_Handler=vPortSVCHandler

有关ld --defsym 选项以及链接器脚本中的分配的更多信息,请参见binutils文档。


2
只需在链接器脚本的顶部添加“SVC_Handler = vPortSVCHandler;”即可完成工作。看起来仍然有点混乱,但它可以运行。 - Brian McFarland
1
请注意,此解决方案似乎根本无法与LTO一起使用。它似乎总是发出指向0x0的符号,导致生成的指令中出现“CALL 0”。 - Craig Younkins
一个不错的事情是,这也适用于那些在一些CUs中仅可见为extern的变量,在这种情况下别名解决方案也无法起作用。 - stefanct

3

我认为别名的问题在于它需要一个已声明和定义的函数,因为它只是一个别名。您想将其用作另一个函数的前向声明。我已经成功地使用类似的方法解决了这个问题:

void SVC_Handler(void) asm("vPortSVCHandler");

这将重命名SVC_Handler的入口点,如果您未定义它,则应找到vPortSVCHandler。

请参见:https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html

1

我从FreeRTOS示例中获得的另一个解决方案是将以下内容添加到您的FreeRTOSConfig.h文件中...

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

原始文件来自FreeRTOS/Demo/CORTEX_M0_LPC1114_LPCXpresso/RTOSDemo/Source/FreeRTOSConfig.h,该文件还将CMSIS系统时钟集成到配置中。这是一个非常好的CMSIS/FreeRTOS项目的起点。

0

我相信SVC处理程序仅在FreeRTOS的初始启动时使用,因此添加一个间接异常处理程序不会影响性能(但很丑陋)。最好在FreeRTOS论坛上询问此问题,那里的回复通常很好。

希望这可以帮到你,最好的祝福,戴夫


1
我应该补充说明,我还需要在SysTick和PendSV处理程序中执行此操作。我可能也会在FreeRTOS论坛上提问,但这实际上更多是关于GCC工具链而不是FreeRTOS的问题。 - Brian McFarland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接