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"
...
);
}
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. –
@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. –