Я работаю с GCC-ARM-Embedded и FreeRTOS. FreeRTOS имеет функцию vTaskSwitchContext()
, которая используется только в некотором встроенном ассемблерном коде.Предотвращение отказа от функции GCC LTO
Проблема: когда я использую 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"
...
);
}
Интересно, как это может произойти. Компилятор видит объектные файлы и их внешние ссылки. Не имеет значения, ссылается ли символ на код C или встроенную сборку. –
@undur_gongor: LTO меняет много вещей и может вызвать сюрпризы, в общем. «Линкер» на самом деле не видит объектные файлы и внешние ссылки, скорее, компоновщик выступает в качестве front-end для конечного компилятора, а затем связывает результаты с исходным кодом компилятора. –