防止 GCC LTO 删除函数
Prevent GCC LTO from deleting function
我使用 GCC-ARM-Embedded 和 FreeRTOS。
FreeRTOS 具有 vTaskSwitchContext()
函数,仅在某些情况下使用
内联汇编代码。
问题是:当我使用LTO时,GCC不考虑内联汇编代码,认为没有使用该功能,因此将其删除。然后链接器失败,因为无法解析内联汇编代码中的函数调用。
我会申请 __attribute__((used))
但我不想接触 FreeRTOS 代码(它由 STM32CubeMX 生成)。
我试着把它放在我的代码中,但实际上 GCC 足够聪明,不允许它工作:
if(false)
vTaskSwitchContext();
有没有什么方法可以在不同的源文件中或通过参数告诉 GCC 不应删除此函数?
例子
// file1.c
void vTaskSwitchContext( void )
{
...
}
// file2.c
void xPortPendSVHandler( void )
{
__asm volatile
(
...
" isb \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
...
);
}
尝试从标记为 used
.
的单独函数调用该函数
void dummyFunction(void) __attribute__((used));
// Never called.
void dummyFunction(void) {
vTaskSwitchContext();
}
您可以将 -Wl,--undefined=vTaskSwitchContext
添加到您的 LDFLAGS
。
出于某种原因,Dietrich 提出的解决方案对我不起作用。我正在使用 Infineon 的 DAVE 4(基本上是 eclipse,带有用于其 XMC 微控制器系列的精美代码生成插件),这可能是它不起作用的原因。对我来说,我必须在 vTaskStartScheduler()
:
之后调用 vTaskSwitchContext()
int main(){
initializationCode();
vTaskStartScheduler();
//Code never reaches here
vTaskSwitchContext();
}
如果您使用的 FreeRTOS 版本已经为 vTaskSwitchContext()
使用了宏 portDONT_DISCARD
,您可以在自己的 portmacro.h
中定义 portDONT_DISCARD
#define portDONT_DISCARD __attribute__((used))
本质上是向后移植https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e
我使用 GCC-ARM-Embedded 和 FreeRTOS。
FreeRTOS 具有 vTaskSwitchContext()
函数,仅在某些情况下使用
内联汇编代码。
问题是:当我使用LTO时,GCC不考虑内联汇编代码,认为没有使用该功能,因此将其删除。然后链接器失败,因为无法解析内联汇编代码中的函数调用。
我会申请 __attribute__((used))
但我不想接触 FreeRTOS 代码(它由 STM32CubeMX 生成)。
我试着把它放在我的代码中,但实际上 GCC 足够聪明,不允许它工作:
if(false)
vTaskSwitchContext();
有没有什么方法可以在不同的源文件中或通过参数告诉 GCC 不应删除此函数?
例子
// file1.c
void vTaskSwitchContext( void )
{
...
}
// file2.c
void xPortPendSVHandler( void )
{
__asm volatile
(
...
" isb \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
...
);
}
尝试从标记为 used
.
void dummyFunction(void) __attribute__((used));
// Never called.
void dummyFunction(void) {
vTaskSwitchContext();
}
您可以将 -Wl,--undefined=vTaskSwitchContext
添加到您的 LDFLAGS
。
出于某种原因,Dietrich 提出的解决方案对我不起作用。我正在使用 Infineon 的 DAVE 4(基本上是 eclipse,带有用于其 XMC 微控制器系列的精美代码生成插件),这可能是它不起作用的原因。对我来说,我必须在 vTaskStartScheduler()
:
vTaskSwitchContext()
int main(){
initializationCode();
vTaskStartScheduler();
//Code never reaches here
vTaskSwitchContext();
}
如果您使用的 FreeRTOS 版本已经为 vTaskSwitchContext()
使用了宏 portDONT_DISCARD
,您可以在自己的 portmacro.h
portDONT_DISCARD
#define portDONT_DISCARD __attribute__((used))
本质上是向后移植https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e