2016-07-15 6 views
5

Я работаю с 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" 
    ... 
    ); 
} 
+0

Интересно, как это может произойти. Компилятор видит объектные файлы и их внешние ссылки. Не имеет значения, ссылается ли символ на код C или встроенную сборку. –

+0

@undur_gongor: LTO меняет много вещей и может вызвать сюрпризы, в общем. «Линкер» на самом деле не видит объектные файлы и внешние ссылки, скорее, компоновщик выступает в качестве front-end для конечного компилятора, а затем связывает результаты с исходным кодом компилятора. –

ответ

6

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

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

// Never called. 
void dummyFunction(void) { 
    vTaskSwitchContext(); 
} 
Смежные вопросы