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

[avr-gcc][c][m8]Wywoływanie funkcji przez wskaźnik. Adresy w mapfile.

cavendish 28 Lip 2012 17:54 1832 6
  • #1 11152603
    cavendish
    Poziom 17  
    Witam.

    Mam pytanie do specjalistów od avr i gcc. Chcę zrobić sobie debuger do atmegi8, który będzie w stanie odczytywać lub ustawiać po rs232 wartości zmiennych oraz wywoływać funkcje. W zamyśle po zlinkowaniu kodu make wywoływać ma skrypt w pelru, który parsuje .map file w poszukiwaniu zmiennych statycznych i globalnych oraz adresów funkcji. Potem według scenariusza testowego wywoływać ma odpowiednie funkcje i ustawiać zmienne. O ile ze zmiennymi z sekcji .data - ich ustawianiem i odczytem - poszło łatwo, o tyle mam kłopot z wywołaniem funkcji.

    Oto wycinek mapfile, z którego dowiaduję się jaki adres ma interesująca mnie funkcja:
    .text.__dispToggleBacklight
    
                    0x000008e2        0xa ../disp/disp.o


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Definiuję sobie wskaźnik na funkcję jako zmnienną globalną:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W mainie ładuję go wartością, póki co "ręcznie" odczytaną z mapfile i próbuję wywołać funkcję:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Skutek jest taki, że funkcja wywołuje się i wykonywane jest to co powinno być zrobione ale potem program idzie w przysłowiowe krzaki, i wymaga restartu. Wygląda jakby funkcja nie powracała z wywołania.
    ?
  • #2 11153485
    krru
    Poziom 33  
    A parametry się zgadzają? tj dispToggleBacklight jest bezparametrowa?
  • #3 11153519
    cavendish
    Poziom 17  
    Zapomniałem dodać. Niżej prototyp danej funkcji:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #4 11153710
    zumek
    Poziom 39  
    cavendish napisał:
    ...W mainie ładuję go wartością, póki co "ręcznie" odczytaną z mapfile i próbuję wywołać funkcję:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Skutek jest taki, że funkcja wywołuje się i wykonywane jest to co powinno być zrobione ale potem program idzie w przysłowiowe krzaki, i wymaga restartu. Wygląda jakby funkcja nie powracała z wywołania.
    ?


    Jeśli z jakiegoś powodu, wolisz "ręcznie" wpisywać adres funkcji, to nie zapominaj, że masz do czynienia z AVR-em :D
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 11154152
    cavendish
    Poziom 17  
    zumek napisał:
    Jeśli z jakiegoś powodu, wolisz "ręcznie" wpisywać adres funkcji, to nie zapominaj, że masz do czynienia z AVR-em

    Nie zapominam, tylko zwyczajnie się na nich nie znam :(.

    Jaszcze zanim przeczytałem Twojego posta zrobiłem tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Z zaskoczeniem stwierdziłem, że działa. Wyrzuciłem sobie na wyświetlacz tenże adres, co powinienem był zrobić najpierw, i z jeszcze większym zdumieniem stwierdziłem, że wynosi on połowę adresu, który odczytałem z pliku .map. Zauważyłem, że wszystkie funkcje mają adresy będące wielokrotnością dwójki oraz, że robione jest prawdopodobnie ich wyrównywanie do dwóch:

    . = ALIGN (0x2)

    Teraz stoję przed pytaniem: o co chodzi?
  • Pomocny post
    #6 11154576
    kiziu13
    Poziom 17  
    Mnożenie/dzielenie przez 2 w AVRach związane jest z przejściem z adresacji słowowej, która obecna jest w pamięci FLASH AVRów, na adresację bajtową, która używana jest przez AVR-GCC. Z tego samego względu wszelkie sekcje muszą być parzystej długości, w AVRach adresuje się słowo, nie bajt.
REKLAMA