Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[AT91SAM7S][C++]undefined reference to `__dso_handle'

Krotki 19 Maj 2008 21:31 4097 12
  • #1 19 Maj 2008 21:31
    Krotki
    Poziom 13  

    Witam,

    Mam mały problem z wykorzystaniem bibliotek np list (Standardowy STL) czy iostrem w malym projekcie testowym. Otóż napisalem prosta aplikacje do zapalania i gaszenia diod poprzez port DBGU.

    Code:

    #include "test.h"

    void tLED(unsigned int p) {
       if((AT91C_BASE_PIOA->PIO_ODSR & p) == p) {
          AT91C_BASE_PIOA->PIO_CODR = p;
       } else {
          AT91C_BASE_PIOA->PIO_SODR = p;
       }
    }

    void printMenu() {
       AT91F_DBGU_Printk("\r\nMenu On/Off:\r\n");
       AT91F_DBGU_Printk("0.Help 1.LED1 2.LED2 3.LED3 4.LED4 5.LED5 6.LED6 7.LED7 8.LED8\r\n\r\n");
    }

    int main(void)
    {
       AT91C_BASE_PIOA->PIO_PER = 0xFF;
       AT91C_BASE_PIOA->PIO_OER = 0xFF;
       AT91C_BASE_PIOA->PIO_PPUER = 0xFF;
       AT91C_BASE_PIOA->PIO_CODR = 0xFF;
       
       unsigned int i;

       AT91F_DBGU_Init();
       AT91F_DBGU_Printk("Test LED\r\n");
       printMenu();

       while(1) {
          AT91F_DBGU_Printk(":");
          AT91F_DBGU_scanf("%i", &i);
          AT91F_DBGU_Printk("\r\n");
          
          switch (i) {
          case 0 :
             printMenu();
             break;
          case 1 :
             tLED(AT91C_PIO_PA0);
             break;
          case 2 :
             tLED(AT91C_PIO_PA1);
             break;
          case 3 :
             tLED(AT91C_PIO_PA2);
             break;
          case 4 :
             tLED(AT91C_PIO_PA3);
             break;
          case 5 :
             tLED(AT91C_PIO_PA4);
             break;
          case 6 :
             tLED(AT91C_PIO_PA5);
             break;
          case 7 :
             tLED(AT91C_PIO_PA6);




             break;
          case 8 :
             tLED(AT91C_PIO_PA7);
             break;
          default:
             AT91F_DBGU_Printk("Nie rozpoznano komendy\r\n");
             break;
          }
       }
       
       return 0;
    }


    Wszystko ładnie się gasi/zapala no więc sobie myślę ze czas sprawdzić funkcjonalność bibliotek STL i wykombinowalem maly dodatek do poprzedniego programu:

    Code:

    #include <iostream>
    #include <list>
    #include "test.h"


    std::list<int> A;
    std::list<int>::iterator AIt;


    void tLED(unsigned int p) {
       if((AT91C_BASE_PIOA->PIO_ODSR & p) == p) {
          AT91C_BASE_PIOA->PIO_CODR = p;
       } else {
          AT91C_BASE_PIOA->PIO_SODR = p;
       }
    }

    void printMenu() {
       AT91F_DBGU_Printk("\r\nMenu On/Off:\r\n");
       AT91F_DBGU_Printk("0.Help 1.LED1 2.LED2 3.LED3 4.LED4 5.LED5 6.LED6 7.LED7 8.LED8\r\n\r\n");
    }

    int main(void)
    {
       AT91C_BASE_PIOA->PIO_PER = 0xFF;
       AT91C_BASE_PIOA->PIO_OER = 0xFF;
       AT91C_BASE_PIOA->PIO_PPUER = 0xFF;
       AT91C_BASE_PIOA->PIO_CODR = 0xFF;
       
       unsigned int i;

       AT91F_DBGU_Init();
       AT91F_DBGU_Printk("Test LED\r\n");
       printMenu();

       A.push_front(1);
       A.push_front(2);
       A.push_front(3);
       A.push_front(4);
       
       while(1) {
          for (AIt = A.begin(); AIt!=A.end(); ++AIt) {
              cout << *AIt << endl;
          }
          
          std::cout << "ala ma kota";
          
          AT91F_DBGU_Printk(":");
          AT91F_DBGU_scanf("%i", &i);
          AT91F_DBGU_Printk("\r\n");
          
          switch (i) {
          case 0 :
             printMenu();
             break;
          case 1 :
             tLED(AT91C_PIO_PA0);
             break;
          case 2 :
             tLED(AT91C_PIO_PA1);
             break;
          case 3 :
             tLED(AT91C_PIO_PA2);
             break;
          case 4 :
             tLED(AT91C_PIO_PA3);
             break;
          case 5 :
             tLED(AT91C_PIO_PA4);
             break;
          case 6 :
             tLED(AT91C_PIO_PA5);
             break;
          case 7 :
             tLED(AT91C_PIO_PA6);
             break;
          case 8 :
             tLED(AT91C_PIO_PA7);
             break;
          default:
             AT91F_DBGU_Printk("Nie rozpoznano komendy\r\n");
             break;
          }
       }
       
       return 0;
    }


    Problem w tym że kompilacja przebiega normalnie ale przy linkowaniu aplikacji dostaje błąd:

    c:/program files/yagarto/bin/../arm-elf/include/c++/4.2.2/iostream:77: undefined reference to `__dso_handle'

    Jak wywalę iostream i wyżce odnośniki do cout to widze takie cos:

    c:/program files/yagarto/bin/../arm-elf/include/c++/4.2.2/bits/stl_list.h:124: undefined reference to `__dso_handle'

    Myślałem że są to problemy z tak zwanymi statycznymi konstruktorami, ale kombinuje i nadal nie wiem o co tu chodzi... Może ktoś łaskawy zajrzy w projekt i coś doradzi ? Z pewnością zarobi u mnie piwo :P

    0 12
  • #2 19 Maj 2008 22:22
    fantom
    Poziom 31  

    A libstdc++ dolaczone podczas linkowania ? Ide o zaklad ze nie bardzo ;-).

    0
  • #3 19 Maj 2008 22:54
    Krotki
    Poziom 13  

    Właśnie z tego co się orientuje to jest :)
    Tak wygada linkowanie:

    arm-elf-g++ -mcpu=arm7tdmi -I. -gdwarf-2 -DROM_RUN -DVECTORS_IN_RAM -D__WinARM__ -D__WINARMSUBMDL_AT91SAM7S256__ -D__WINARMBOARD_PROPOX_EVBSAM7S__ -Os -Wall -Wcast-align -Wimplicit -Wpointer-arith -Wswitch -ffunction-sections -fdata-sections -Wredundant-decls -Wreturn-type -Wshadow -Wunused -Wa,-adhlns=common/Cstartup.lst -I./common -MD -MP -MF .dep/test.elf.d common/Cstartup.o common/swi_handler.o dbgu.o syscalls.o swi_handler_user.o common/Cstartup_SAM7.o test.o --output test.elf -nostartfiles -Wl,-Map=test.map,--cref,--gc-sections -lm -lc -lgcc -lstdc++ -L./common -T./common/AT91SAM7S256-ROM.ld

    0
  • #4 20 Maj 2008 07:57
    fantom
    Poziom 31  

    Hmm przeszukalem google i wyglada na to ze jest to jakis bug w gcc. Sprobuj dac -lgcc na koncu tzn. po wszystkich innych bibliotekach.

    0
  • #5 21 Maj 2008 00:25
    Krotki
    Poziom 13  

    Oczywiście także szukając na googlu znalazłem informacje że niektóre wersje gcc mogą posiadać błąd tyle że ten mój przypadek był nieco inny. Dla potwierdzenia ze to nie gcc ściągnąłem yagarto wcześniejsze i błąd był ten sam.
    Probowałem także modyfikować wpisy w skrypcie linkera bo sie także doszukałem ze zła inicjalizacja konstruktorów globalnych może takie coś powodować, ale bez skutku.
    Potem przyszedł czas na poszukanie i skompilowanie jakiegoś dowolego projektu w c++. I okazało się że tam __dso_handle było zdefiniowane w pliku crtbegin.o. Znalazłem plik w ścieżce gcc ale nie wiedziałem jak go poprawnie podpiąć wiec doszedłem w końcu że coś nie tak z parametrami linkowania. Oczywiście pierwszym odruchem było przestawianie bibliotek - nic. Potem jakieś lekkie zmiany w makefile'u. W tym momencie wyrwałem sobie już sporo kłaków i postanowiłem napisać tutaj. Jak już fantom zmusił mnie do napisania w jaki sposób linkuje (za co serdecznie dziękuje ! ;p) stwierdziłem ze nie wszystkie parametry znam. Po wygooglowaniu wszystkich których nie znalem okazało sie że parametr -nostartfiles mówi kompilatorowi żeby nie dodawał bibliotek gcc czy jakoś tak. I kompilacja sie wrzeszczcie zakończyła!!!

    Nauka na przyszłość nie kopiuj makefile'ow jak nie wiesz co w nich jest ;p

    Mam jeszcze jedno pytanie otóż plik wynikowy jest nieco duży 59k bin, hex jakieś 160k i to tylko gdy użyłem list. Jak dokładam iostream to hex przebija 280k. Czy to jest normalne ?

    0
  • #6 21 Maj 2008 08:30
    fantom
    Poziom 31  

    Krotki napisał:
    Po wygooglowaniu wszystkich których nie znalem okazało sie że parametr -nostartfiles mówi kompilatorowi żeby nie dodawał bibliotek gcc czy jakoś tak. I kompilacja sie wrzeszczcie zakończyła!!!


    I tak mnie to dziwi bo ten blad jest zwiazany z dolaczaniem bibliotek dynamicznych a tych jak wiadomo nie ma mozliwosci uzyc przy kompilowaniu skrosnym na inne architektury i wszystkie biblioteki powinny byc linkowane statycznie. Pytanie tylko czy ten kod w ogole bedzie smigal ? Chyba ze juz sprawdzales.

    Cytat:

    Mam jeszcze jedno pytanie otóż plik wynikowy jest nieco duży 59k bin, hex jakieś 160k i to tylko gdy użyłem list. Jak dokładam iostream to hex przebija 280k. Czy to jest normalne ?


    Szczerze ? Jakos mnie to nie dziwi ;-). C++ po prostu.

    0
  • #7 21 Maj 2008 12:49
    Krotki
    Poziom 13  

    Hmmm wygląda na to ze nie śmiga na procu ... wystarczy ze stary program bez tej dyrektywy z linkuje i tez nie śmiga. Naprawdę nie czaje już tego ... To niby jak mam programować w C++ ? Od początku wszystkie biblioteki samemu zrobić ?

    0
  • #8 21 Maj 2008 13:09
    fantom
    Poziom 31  

    Krotki napisał:
    Hmmm wygląda na to ze nie śmiga na procu ... wystarczy ze stary program bez tej dyrektywy z linkuje i tez nie śmiga. Naprawdę nie czaje już tego ... To niby jak mam programować w C++ ? Od początku wszystkie biblioteki samemu zrobić ?


    Osobiscie zrobil bym deasemblacje krotkiego kodu lub zdebugowal go zeby w ogole wiedziec o co kaman.Osobiscie omijam C++ z daleka jesli chodzi o mikrokontrolery, nie zeby to bylo niemozliwe ale napewno wiecej problemow a korzysci znikome, wrecz zadne. Byc moze w tym przypadku wcale nie chodzi o C++ a naprzyklad o zly skrypt linkera lub nie do konca poprawny kod startowy, sprobuj napisac prosty programik w C i zobaczyc czy dziala, potem rownie prosty w C++, przeanalizuj hex-a i zobacz czy kod laduje sie pod prawidlowy adres, czy wektor resetu jest inicjalizowany prawidlowo, duzo tego moze byc.

    0
  • #9 24 Maj 2008 10:21
    Krotki
    Poziom 13  

    Cóż poddałem się z C++. Przesiadam sie na C. Przetestowałem jeszcze Keila z GCC + H-JTAG i powiem ze to środowisko wydaje mi się o wiele wygodniejsze od YAGARTO. Problem jest tylko taki ze makefile'a nie ma i ciezko potem kompilować na innych maszynach, chociaż Keil potrafi wypluć BAT'a do automatyzacji.

    0
  • #10 25 Maj 2008 20:05
    fantom
    Poziom 31  

    Krotki napisał:
    Cóż poddałem się z C++. Przesiadam sie na C. Przetestowałem jeszcze Keila z GCC + H-JTAG i powiem ze to środowisko wydaje mi się o wiele wygodniejsze od YAGARTO. Problem jest tylko taki ze makefile'a nie ma i ciezko potem kompilować na innych maszynach, chociaż Keil potrafi wypluć BAT'a do automatyzacji.


    Keila z GCC ? Chyba cos nie tego. Keil to Keil a GCC to GCC.

    0
  • #11 26 Maj 2008 11:24
    Krotki
    Poziom 13  

    A właśnie sam Keil tzn środowisko uVision udostępnia możliwość podpięcia GCC i wtedy mamy darmowe środowisko z nieograniczonym w żaden sposób kodem. Poza tym podpinając przez interfejs RDDI H-JTAG'a nie musimy korzystać z OpenOCD i ładnie wszystko śmiga. Osobiście miałem sporo problemów z OpenOCD i do tej pory nie odpaliłem debuggera w Yagarto. Jedyne co mi nie pasuje w keilu to brak podpowiedzi przy pisaniu kodu i brak makefile'a.

    0
  • #12 13 Sty 2011 10:07
    Jagged
    Poziom 10  

    Witam, przepraszam, że odkopuje temat. Trafiłem tu przez googla, nie znalazłem tu rozwiązania, jednak znalazłem rozwiązanie i chce się nim podzielić, by inne osoby, które trafią przez google na ten temat, znalazły rozwiązanie.

    Wystarczy dodać opcje kompilatora "-fno-use-cxa-atexit" i wszystko się kompiluje, a co najważniejsze działa w praktyce.

    1
  • #13 17 Wrz 2013 09:24
    wacu85
    Poziom 1  

    A dla tych którzy chcą wiedzieć o co chodzi z tą magiczną opcją:

    Otóż 'normalny' program c++ woła konstruktory obiektów statycznych przed main'em i ich destruktory po main'ie. Właśnie do wołania destruktorów obiektów statycznych jest potrzebne `__dso_handle'. Opcja "-fno-use-cxa-atexit" w skrócie wyłącza wołanie tych destruktorów przez co likwiduje odwołania do `__dso_handle'

    1
  Szukaj w 5mln produktów