2016-07-15 204 views
5

Lavoro con GCC-ARM-Embedded e FreeRTOS. FreeRTOS ha la funzione vTaskSwitchContext() che viene utilizzata solo in alcuni codice assemblatore in linea.Impedire a GCC LTO di eliminare la funzione

Il problema è: quando utilizzo LTO, GCC non considera il codice assemblatore in linea e pensa che la funzione non sia utilizzata, quindi la rimuove. Quindi il linker non riesce perché la chiamata di funzione nel codice assembler inline non può essere risolta.

Applicherò __attribute__((used)) ma non voglio toccare il codice FreeRTOS (è generato da STM32CubeMX).

Ho provato a mettere nel mio codice, ma in realtà GCC è abbastanza intelligente per non permettere che questo lavoro:

if(false) 
    vTaskSwitchContext(); 

c'è qualche modo per dire GCC in un file di origine diversa, o tramite il parametro, che questa funzione non dovrebbe essere rimossa?

Esempio

// file1.c 
void vTaskSwitchContext(void) 
{ 
    ... 
} 

// file2.c 
void xPortPendSVHandler(void) 
{ 
    __asm volatile 
    (
    ... 
    " isb         \n" 
    " bl vTaskSwitchContext    \n" 
    " mov r0, #0       \n" 
    ... 
    ); 
} 
+0

Mi chiedo come possa accadere. Il linker vede i file oggetto e i loro riferimenti esterni. Non dovrebbe importare se un simbolo è referenziato dal codice C o dall'assieme in linea. –

+0

@undur_gongor: LTO cambia molte cose e può causare sorprese, in generale. Il "linker" in realtà non vede file oggetto e riferimenti esterni, piuttosto, il linker funge da front-end al back-end del compilatore e quindi collega i risultati dal back-end del compilatore. –

risposta

6

Prova chiamare la funzione da una funzione separata che è contrassegnata used.

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

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