2012-12-05 6 views
6

Próbuję zbudować prosty projekt wykorzystujący Yagarto i Eclipse dla platformy mikrokontrolera ARM. W moim kodu startowego, mam to (co moim zdaniem jest dość standardowe i nieciekawe):Dlaczego mam undefined odwołanie do _init w __libc_init_array?

void Reset_Handler(void) 
{ 
    /* Initialize data and bss */ 
    __Init_Data(); 

    /* Call CTORS of static objects */ 
    __libc_init_array(); 

    /* Call the application's entry point.*/ 
    main(); 

    while(1) { ; } 
} 

ile mogę wypowiedzieć się na wezwanie do __libc_init_array(), pojawia się następujący komunikat o błędzie z łącznikiem:

arm-none-eabi-g++ -nostartfiles -mthumb -mcpu=cortex-m4 -TC:/Users/mark/workspace/stm32_cpp_test/STM32F40x_1024k_192k_flash.ld -gc-sections -Wl,-Map=test_rom.map,--cref,--no-warn-mismatch -o stm32_cpp_test "system\\syscalls.o" "system\\startup_stm32f4xx.o" "system\\mini_cpp.o" "system\\cmsis\\system_stm32f4xx.o" main.o 
d:/utils/yagarto/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib/thumb/v7m\libg.a(lib_a-init.o): In function `__libc_init_array': 
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\thumb\v7m\newlib\libc\misc/../../../../../../../newlib-1.20.0/newlib/libc/misc/init.c:37: undefined reference to `_init' 
collect2.exe: error: ld returned 1 exit status 

Dlaczego otrzymuję błąd "nieokreślonego odniesienia"? czego mi brakuje? Zakładam, że brakuje jakiejś flagi linkera, ale nie mogę dla mnie dowiedzieć się, co.

Odpowiedz

5

Nie jestem ekspertem, ale:

Prawdopodobnie _init (normalny czas pracy punktu wejścia) odwołuje się do kodu, który wykonuje konstruktor i dtor tabele.

Używasz -nostartfiles, więc unikaj standardowego uruchamiania i prawdopodobnie cały kod startowy jest eliminowany przez -gc-sections. Wywołanie jawne dodaje ponownie odwołanie.

Jeśli pominięcie --g-sekcje go nie rozwiąże, może to być także brakująca instrukcja keep() w twoim (osadzonym) skrypcie linkera, który utrzymuje kod wpisu przez cały czas, lub twój własny kod startowy (startup_ *) należy odwołać to

+0

Tak więc, jeśli dodaję pustą _init (void) {} ​​do mojego kodu startowego, kompiluje się dobrze. Zastanawiam się, co powinna zrobić ta funkcja? – Mark

+0

_init jest zwykle punktem w systemie binarnym, do którego przeskakuje system operacyjny, jeśli załadowano plik binarny. Domyślna etykieta punktu wejścia mniej lub więcej. Sposób rozwiązania problemu zależy od konfiguracji wbudowanego systemu ładującego. Wydaje mi się, że ten toolchain nie jest idealnie przeniesiony. –

+0

Nie mam "wbudowanego systemu ładującego", sam napisałem kod startowy (lub, dokładniej, skopiowałem + wkleiłem go z Internetu) ... To jest Cortex-M4, a ResetHandler jest pierwszym (i tylko) rzeczy wykonane. – Mark

4

podstarzały pytanie, ale napotkał podobny problem i rozwiązanie było jak wskazano Marco van de Voort, jeśli masz zamiar używać __libc_init_array należy pominąć opcję -nostartfiles łącznika, aby to normalne funkcje init libc. Duplikat odpowiedzi.

Po drugie, sugerowałbym dołączenie flagi --specs=nano.specs podczas łączenia z ramieniem gcc (uważam yargarto za widelec lub nawet prekompilację gcc-arm), ponieważ redukuje to zużycie kodu libc itd.

Powiązane problemy