Предотвратить GCC 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 ответа

Решение

Попробуйте вызвать функцию из отдельной функции, которая помечена used,

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

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

Можете добавить -Wl,--undefined=vTaskSwitchContext на ваш LDFLAGS,

По какой-то причине решение, которое предложил Дитрих, у меня не сработало. Я использую Infineon DAVE 4 (в основном eclipse с модным плагином генерации кода для их линейки микроконтроллеров XMC), что может быть причиной того, что это не сработало. Мне пришлось позвонитьvTaskSwitchContext() после vTaskStartScheduler():

int main(){

    initializationCode();

    vTaskStartScheduler();

    //Code never reaches here
    vTaskSwitchContext();
}

Если ваша версия FreeRTOS уже использует макрос для vTaskSwitchContext()вы можете определить portDONT_DISCARDв своем собственном portmacro.h

      #define portDONT_DISCARD __attribute__((used))

По сути, бэкпорт https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/07e672c448e2a4ea56ae793f1c6dae26d908b16e

Другие вопросы по тегам