防止GCC LTO删除功能

时间:2016-07-15 06:56:26

标签: c gcc ld freertos lto

我使用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"
    ...
    );
}

4 个答案:

答案 0 :(得分:8)

尝试从标记为used

的单独函数调用该函数
void dummyFunction(void) __attribute__((used));

// Never called.
void dummyFunction(void) {
    vTaskSwitchContext();
}

答案 1 :(得分:4)

您可以将-Wl,--undefined=vTaskSwitchContext添加到LDFLAGS

答案 2 :(得分:0)

由于某种原因,Dietrich提出的解决方案对我不起作用。我正在使用Infineon的DAVE 4(基本上是为他们的XMC微控制器系列配备了精美的代码生成插件的eclipse),这可能是它不起作用的原因。对我来说,我必须在vTaskSwitchContext()之后致电vTaskStartScheduler()

int main(){

    initializationCode();

    vTaskStartScheduler();

    //Code never reaches here
    vTaskSwitchContext();
}

答案 3 :(得分:0)

如果您的 FreeRTOS 版本已经使用 portDONT_DISCARD 的宏 vTaskSwitchContext(),您可以在自己的 portDONT_DISCARD 中定义 portmacro.h

#define portDONT_DISCARD __attribute__((used))

本质上是向后移植 https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e