2016-07-15 27 views
5

löscht Ich arbeite mit GCC-ARM-Embedded und FreeRTOS. FreeRTOS hat die Funktion vTaskSwitchContext(), die nur in einigen Inline-Assembler-Code verwendet wird.Verhindern, dass GCC LTO die Funktion

Das Problem ist: Wenn ich LTO verwende, berücksichtigt GCC den Inline-Assembler-Code nicht und denkt, dass die Funktion nicht verwendet wird, und entfernt sie daher. Der Linker schlägt fehl, da der Funktionsaufruf in dem Inline-Assemblercode nicht aufgelöst werden kann.

Ich würde __attribute__((used)) anwenden, aber ich möchte den FreeRTOS-Code nicht berühren (es wird von STM32CubeMX generiert).

Ich habe versucht, dies in meinem Code setzen, aber eigentlich ist GCC klug genug, dies nicht erlauben zu arbeiten:

if(false) 
    vTaskSwitchContext(); 

Gibt es eine Möglichkeit GCC in einer anderen Quelldatei zu sagen, oder über den Parameter, dass Diese Funktion sollte nicht entfernt werden?

Beispiel

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

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

Ich frage mich, wie das passieren kann. Der Linker sieht Objektdateien und ihre externen Referenzen. Es sollte egal sein, ob ein Symbol von C-Code oder von Inline-Assembly referenziert wird. –

+0

@undur_gongor: LTO ändert viele Dinge und kann im Allgemeinen zu Überraschungen führen. Der "Linker" sieht eigentlich keine Objektdateien und externen Referenzen, sondern der Linker fungiert als Front-End für das Compiler-Backend und verknüpft dann die Ergebnisse vom Compiler-Backend. –

Antwort

6

Versuchen Sie, die Funktion aus einer separaten Funktion aufrufen, die used gekennzeichnet ist.

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

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