[英]Prevent GCC LTO from deleting function
I work with GCC-ARM-Embedded and FreeRTOS.我使用 GCC-ARM-Embedded 和 FreeRTOS。 FreeRTOS has the function vTaskSwitchContext()
which is used only in some inline assembler code. FreeRTOS 具有函数vTaskSwitchContext()
,该函数仅用于某些内联汇编代码。
The problem is: When I use LTO, GCC does not consider the inline assembler code and thinks the function is not used, thus removes it.问题是:当我使用LTO时,GCC没有考虑内联汇编代码并认为该函数没有使用,因此将其删除。 The linker then fails because the function call in the inline assembler code cannot be resolved.然后链接器失败,因为无法解析内联汇编代码中的函数调用。
I would apply __attribute__((used))
but I don't want to touch the FreeRTOS code (it's generated by STM32CubeMX).我会应用__attribute__((used))
但我不想接触 FreeRTOS 代码(它由 STM32CubeMX 生成)。
I tried putting this in my code, but actually GCC is smart enough to not allow this to work:我试着把它放在我的代码中,但实际上 GCC 足够聪明,不允许它工作:
if(false)
vTaskSwitchContext();
Is there some way to tell GCC in a different source file, or via parameter, that this function should not be removed?有没有办法在不同的源文件中或通过参数告诉 GCC 不应删除此函数?
Example示例
// file1.c
void vTaskSwitchContext( void )
{
...
}
// file2.c
void xPortPendSVHandler( void )
{
__asm volatile
(
...
" isb \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
...
);
}
Try calling the function from a separate function which is marked used
.尝试从标记为used
的单独函数调用该函数。
void dummyFunction(void) __attribute__((used));
// Never called.
void dummyFunction(void) {
vTaskSwitchContext();
}
您可以将-Wl,--undefined=vTaskSwitchContext
添加到您的LDFLAGS
。
For some reason, the solution that Dietrich proposed didn't work for me.出于某种原因,Dietrich 提出的解决方案对我不起作用。 I'm using Infineon's DAVE 4 (basically eclipse with a fancy code generation plugin for their line of XMC microcontrollers), which may be the reason why it didn't work.我正在使用 Infineon 的 DAVE 4(基本上是 Eclipse,他们的 XMC 微控制器系列带有一个花哨的代码生成插件),这可能是它不起作用的原因。 For me, I had to call vTaskSwitchContext()
after vTaskStartScheduler()
:对我来说,我不得不在vTaskStartScheduler()
之后调用vTaskSwitchContext()
vTaskStartScheduler()
:
int main(){
initializationCode();
vTaskStartScheduler();
//Code never reaches here
vTaskSwitchContext();
}
If your version of FreeRTOS uses already uses the macro portDONT_DISCARD
for vTaskSwitchContext()
you can define portDONT_DISCARD
in your own portmacro.h
如果您FreeRTOS的用途版本已经使用宏portDONT_DISCARD
的vTaskSwitchContext()
可以定义portDONT_DISCARD
在自己portmacro.h
#define portDONT_DISCARD __attribute__((used))
Essentially backporting https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e基本上向后移植https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.