2016-07-15 25 views
5

Pracuję z GCC-ARM-Embedded i FreeRTOS. FreeRTOS ma funkcję vTaskSwitchContext(), która jest używana tylko w niektórych wbudowanych kodach asemblera .Zapobieganie kasowaniu GCC LTO

Problem polega na tym, że gdy używam LTO, GCC nie bierze pod uwagę wbudowanego kodu asemblera i uważa, że ​​funkcja nie jest używana, więc usuwa je. Łącznik następnie przestaje działać, ponieważ wywołanie funkcji w wbudowanym kodzie asemblera nie może zostać rozwiązane.

Chciałbym zastosować __attribute__((used)), ale nie chcę dotykać kodu FreeRTOS (jest generowany przez STM32CubeMX).

Próbowałem oddanie tego w moim kodu, ale faktycznie GCC jest wystarczająco inteligentny, aby nie pozwalają na to, aby pracować:

if(false) 
    vTaskSwitchContext(); 

Czy istnieje jakiś sposób, aby powiedzieć GCC w innym pliku źródłowego, albo poprzez parametr, który tej funkcji nie należy usuwać?

Przykład

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

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

Zastanawiam się, jak to się może stać. Łącznik widzi pliki obiektów i ich odnośniki zewnętrzne. Nie powinno mieć znaczenia, czy do symbolu odwołuje się kod C, czy z wbudowanego zestawu. –

+0

@undur_gongor: LTO zmienia wiele rzeczy i może generować niespodzianki. "Linker" w rzeczywistości nie widzi plików obiektowych i odnośników zewnętrznych, a raczej linker działa jako front-end do back-endu kompilatora, a następnie łączy wyniki z back-endu kompilatora. –

Odpowiedz

6

Spróbuj wywołaniu funkcji z oddzieleniu oznaczonego used.

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

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