11

我使用 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

4 回答 4

11

尝试从标记为的单独函数调用该函数used

void dummyFunction(void) __attribute__((used));

// Never called.
void dummyFunction(void) {
    vTaskSwitchContext();
}
于 2016-07-15T07:04:12.923 回答
7

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

于 2018-05-04T10:06:23.993 回答
1

出于某种原因,Dietrich 提出的解决方案对我不起作用。我正在使用 Infineon 的 DAVE 4(基本上是 eclipse,为他们的 XMC 微控制器系列提供了一个花哨的代码生成插件),这可能是它不起作用的原因。对我来说,我不得不打电话vTaskSwitchContext()vTaskStartScheduler()

int main(){

    initializationCode();

    vTaskStartScheduler();

    //Code never reaches here
    vTaskSwitchContext();
}
于 2019-06-22T16:28:21.357 回答
0

如果您的 FreeRTOS 版本已经使用了宏portDONT_DISCARDvTaskSwitchContext()您可以portDONT_DISCARD在自己的portmacro.h

#define portDONT_DISCARD __attribute__((used))

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

于 2021-03-29T09:53:33.170 回答