logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

WinAVR: jak wyłączyć prolog/epilog w asemblerze i łączyć C z ASM? undefined reference to main

smmutas 19 Cze 2006 17:44 2468 14
  • #1 2743575
    smmutas
    Poziom 11  
    Posty: 27
    Witam
    Mam kilka pytań.
    1. Czy w WinAVR jest możliwe wyłączenie dodawania przez kompilator prologu i epilogu do każdej wstawki asemblerowej. A jeśli tak to jak ?
    2. Jak połączyć plik napisany w C z plikiem napisanym w asemblerze.


    avr-gcc -Wa,-adhlns=przerwania.lst,-gstabs -Wl,-Map=pierwszy.map,--cref -lm przerwania.S -o przerwania
    C:/WINAVR/BIN/../lib/gcc/avr/3.4.6/../../../../avr/lib/crts8515.o: In function `__vectors':
    ../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined reference to `main'
    make.exe: *** [przerwania] Error 1

    2.1 O co chodzi z tym `main'
    2.2 o co chodzi z crt8515.o jeżeli procesor został określony jako ATmega162

    3. Timer 0 został zaprogramowany następująco

    TCCR0 = (1<<FOC0)|(1<<WGM01) |(1<<COM01)|(1<<CS01);
    OCR0=25;

    Po skompilowaniu i wciągnięciu do AVRStudio widać że liczy poprawnie jednak nie zmienia w symulatorze żadnego pinu wyjściowego.

    Liczę na szybkie odpowiedzi bo czas mnie strasznie pili. :cry:
  • #2 2744686
    GienekS
    Poziom 32  
    Posty: 1971
    Pomógł: 139
    Ocena: 15
    Ujawnij kod, który jest odpowiedzialny za te zmiany na porcie. To może coś poradzimy.
  • #3 2744917
    smmutas
    Poziom 11  
    Posty: 27
    Cały kod to

    void InitTimers_0(void)
    {
    TCCR0 = (1<<FOC0)|(1<<WGM01) |(1<<COM01)|(1<<CS01);
    OCR0=25;
    }
    PORTB.0 jest ustawiany jako wyjście, czyli

    DDRB = 0xFE

    W dokumentacji widnieje że wyjściem dla tego sygnału powinno być PORTB.0

    i to wszystko. A w symulatorze NIC.
  • #4 2745057
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    smmutas napisał:

    
    PORTB.0 jest ustawiany jako wyjście, czyli 
    
    DDRB = 0xFE
    

    W dokumentacji widnieje że wyjściem dla tego sygnału powinno być PORTB.0
    i to wszystko. A w symulatorze NIC.

    Coś Ci się pomyliło :D
    
    DDRB=0x01; //lub DDRB|=(1<<PB0) - PORTB.0 ->wyjście
    

    A Ty ustawiłaś cały PORTB jako wyjście , za wyjątkiem właśnie bitu PB0.
    Popraw i powinno sie "symulować"
    Jeśli zaś chodzi o pliki asm , to w GCC muszą mieć rozszerzenie *.s (małe s) , bo pliki *.S (duże S) generuje kompilator C - jeśli pamięć mi nie szwankuje :D
    Natomiast co do prolog i epilog w funkcji , to trzeba użyć artybutu naked.
    To tyle.

    Piotrek
  • #5 2748294
    smmutas
    Poziom 11  
    Posty: 27
    Witam. Jeśli chodzi o ustawianie wyjść to miałeś rację, aby ustawić wyjście należy wpisać 1 do DDR. sprawdziłem chyba wszystkie możliwe kombinacje i nadal symulator się na mnie wypina.
    W sprawie plików asemblerowych to rozszerzenie powinno być *.S ( duże S ), bo pliki z małym s są tworzone przez kompilator i usuwane przez ( Make Clean ).

    Kolejne pytanie :

    Jak użyć atrybutu "naked" ?

    Pozdrawiam.
  • #6 2748402
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    smmutas napisał:

    Kolejne pytanie :

    Jak użyć atrybutu "naked" ?

    Pozdrawiam.

    
    #include <avr/io.h>
    
    void naked_func() __attribute__ ((naked));
    
    void func()
    {
    asm("nop");
    }
    /* wygenerowany kod asm bez optymalizacji
    void func()
            PUSH    R28              
            PUSH    R29              
            IN      R28,0x3D         
            IN      R29,0x3E         
            NOP                      
            POP     R29              
            POP     R28              
            RET
    */                      
    void naked_func()
    {
    asm("nop");
    asm ("ret");//"gołą" funkcję MUSISZ zakończyć RET,
                // bo inaczej procek pójdzie w krzaki,
    			// chyba że wiesz co robisz ;)
    }
    /* wygenerowany kod asm bez optymalizacji
    void naked_func()
           NOP 
           RET  
    */
    
    int main(void)
    {
    func();
    naked_func();
    return(0);
    }
    

    Tak to mniejwięcej wygląda , a reszta w manualu :D
    Piotrek

    PS
    Co do S i s , to faktycznie pomyliłem "kapitaliki" :|
  • #7 2751859
    smmutas
    Poziom 11  
    Posty: 27
    Wielkie dzięki za wyjaśnienia. Problem jednak pozostał.
    Potrzebuję jeszcze wiedzy
    1. Jak zastosować atrybut "naked" dla obsługi przerwania bo głównie tu kompilator dorzuca od siebie wiele różości.
    2. Czy można kompilatorowi zabronić urzywania niektórych rejestrów ?

    Najwięcej radości sprawiłoby mi poznanie metody łączenia plików *.c i *.S
    mnie kompilator wnerwia komunikatem

    Compiling: pierwszy.c
    avr-gcc -c -mmcu=atmega162 -I. -gstabs -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=pierwszy.lst -std=gnu99 -morder1 -Wp,-M,-MP,-MT,pierwszy.o,-MF,.dep/pierwszy.o.d pierwszy.c -o pierwszy.o
    avr-gcc -Wl,-Map=pierwszy.map,--cref -lm przerwania.o -o przerwania
    C:/WINAVR/BIN/../lib/gcc/avr/3.4.6/../../../../avr/lib/crts8515.o: In function `__vectors':
    ../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined reference to `main'
    make.exe: *** [przerwania] Error 1

    Czy ktoś zna na to jakiś sposób ?
  • #8 2751996
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    smmutas napisał:

    1. Jak zastosować atrybut "naked" dla obsługi przerwania bo głównie tu kompilator dorzuca od siebie wiele różości.

    Tak samo jak dla funkcji :D
    smmutas napisał:

    2. Czy można kompilatorowi zabronić urzywania niektórych rejestrów ?

    Prawdopodobnie TAK - dokumentacja.
    smmutas napisał:

    Najwięcej radości sprawiłoby mi poznanie metody łączenia plików *.c i *.S
    mnie kompilator wnerwia komunikatem

    Niby skąd mamy wiedzieć , coś "nawywijał" :(
    Źle zbudowany projekt , i/lub makefile , lub plik *.S

    Piotrek
  • #9 2763621
    smmutas
    Poziom 11  
    Posty: 27
    Pomimo wielu prób zastosowania atrybutu "naked" do procedury obsługi przerwania w sposób ( w sposób mniej lub bardzej ścisły ) sugerowany przez kolegę Zunka - Piotrka nadal jestem w pyrach. Kompilator twierdzi , że ten atrybut nadaje się tylko do funkcji.
    Czy możliwa jest inna droga ?
  • #11 2763658
    smmutas
    Poziom 11  
    Posty: 27
    W sprawie łączenia programu w C i w asemblerze. Całość składała się z dwu plików jedn w C zawierający funkcję main() oraz inicjalizację portów i timerów oraz o zewnętrznie zdefiniowanych procedurach obsługi przerwań.
    Plik asemblerowy zawierał tylko procedury obsługi przerwań z deklaracją global. W Makefile były oba pliki odpowiednio wpisane. informacja z kompilatora - undefined reference to `main' . gdzie szukać odpowiedzi.

    Dodano po 23 [minuty]:

    Przepraszam kolegę Zunka - Piotrka że chyba tylko tej właściwej metody niesprawdziłem wcześniej. Wielkie dzięki !.:D
  • #12 2763740
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Spakuj kompletny projekt i dodaj jako załącznik , a wnet rozwiążemy problem , bo nie bardzo rozumiem o co Ci chodzi :(

    Piotrek
  • #13 2778208
    smmutas
    Poziom 11  
    Posty: 27
    Przesyłam spakowane pliki które psują mi krew. Ja uzyskuję

    avr-gcc -Wa,-adhlns=przerwania.lst,-gstabs -Wl,-Map=pierwszy.map,--cref -lm przerwania.S -o przerwania
    C:/WINAVR/BIN/../lib/gcc/avr/3.4.6/../../../../avr/lib/crts8515.o: In function `__vectors':
    ../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined reference to `main'
    make.exe: *** [przerwania] Error 1

    Pomimo wielu prób błąd nadal mi się wymyka.:cry:
    Załączniki:
    • proba.rar (20.94 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #14 2778918
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    To ja załączam odpowiedź.To jest prosty przykładzik projektu z AVRStudio , przystosowany do PN-a.Winy za błędną kompilację Twojego projektu , upatruję w makefile i pliku *.S(syntax) ;)

    Piotrek

    PS
    "Przerzuć się" na AVRStudio, a odpadnie Ci kłopot z makfile :D
    Załączniki:
    • sekcje.zip (10.39 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #15 2910120
    smmutas
    Poziom 11  
    Posty: 27
    Dziękuję za rady przeszedłem na AVRStudio. Idzie coraz lepiej.:D

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy problemów z kompilacją i łączeniem kodu asemblerowego (*.S) z kodem w języku C w środowisku WinAVR dla mikrokontrolera ATmega162. Poruszono kwestię wyłączania automatycznie dodawanego przez kompilator prologu i epilogu w asemblerze, co można osiągnąć stosując atrybut funkcji "naked". Przykłady pokazują, jak definiować funkcje i procedury obsługi przerwań z tym atrybutem, w tym użycie makr SIGNAL z atrybutem naked oraz konieczność ręcznego zakończenia funkcji instrukcją RET lub RETI. Omówiono także problem błędu "undefined reference to main" wynikający z nieprawidłowej struktury projektu lub makefile, zwłaszcza gdy plik asemblerowy zawiera tylko procedury przerwań bez funkcji main w C. Wskazano, że pliki asemblerowe powinny mieć rozszerzenie *.S (duże S) i że do poprawnego łączenia konieczne jest posiadanie funkcji main w pliku C. Poruszono także problem konfiguracji portów i timerów, gdzie błędne ustawienie DDRB (np. DDRB=0xFE zamiast DDRB=0x01) powodowało brak efektów w symulatorze. Na koniec zasugerowano przejście na środowisko AVRStudio, które ułatwia zarządzanie projektem i eliminuje problemy z makefile.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA