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

ATmega8A, Asembler i wektory - bad_interrupt Przy większości wektorów

Bartosz36 01 Kwi 2015 20:25 1077 11
REKLAMA
  • #1 14580754
    Bartosz36
    Poziom 12  
    Posty: 91
    Pomógł: 3
    Ocena: 4
    Witam
    Moje krótkie pytanie może niektórym wydać się banalne, ale ostatnio zerknąłem do pliku LSS wygenerowanego przez kompilator (AtmelStudio 6.1) i okazało się, że w tabeli wektorów przerwań przy większości z nich znajduje się komentarz mówiący że: 0x46 <__bad_interrupt>. W całej tabeli tylko wektory o adresie .+54, oraz .+36 (przy okazji, co to znaczy?) wydają się być poprawne...

    Zamieszczam całą tablicę:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Proszę o wytłumaczenie, dlaczego tak się dzieje... czy nie powinno to wyglądać nieco inaczej?
  • REKLAMA
  • #2 14580767
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Do przemyślenia, co miałoby się stać gdybyś miał włączone przerwanie ale nie miał jego obsługi?
  • REKLAMA
  • Pomocny post
    #3 14580842
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Do tego co napisał tadzik85 zauważ, że wszystkie rozkazy skoku wskazują na __bad_interrupt, który wygląda np. tak:

    Kod: text
    Zaloguj się, aby zobaczyć kod

    a jak to działa zrozumiesz analizując swój plik lss.
  • REKLAMA
  • #4 14580877
    Bartosz36
    Poziom 12  
    Posty: 91
    Pomógł: 3
    Ocena: 4
    Czyli jeśli w kodzie C inicjuję jedynie wektor powiedzmy ADC_vect, to jedynie w kodzie asemblerowym jedynie .org ADCaddr będzie pozbawione komentarza <__bad_interrupt>.
    A propos wektorów i tablicy:
    Czy inicjalizacja tablicy wektorów przerwań jest zależna od typu mikrokontrolera? W literaturze i w poradnikach internetowych widzę, że wszędzie wektory mają jednakową inicjalizację: INT0addr to wszędzie INT0addr. Natomiast czytając dokumentację m8 widzę, że tablica zawiera jedynie skok do EXT_INT0. Co stosować w swoim kodzie, by prawidłowo zainicjować tablicę wektorów przerwań?

    Pozdrawiam i dziękuję za odpowiedzi ;)
  • #5 14580889
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Bartosz36 napisał:
    Czyli jeśli w kodzie C inicjuję jedynie wektor powiedzmy ADC_vect, to jedynie w kodzie asemblerowym jedynie .org ADCaddr będzie pozbawione komentarza <__bad_interrupt>.
    A propos wektorów i tablicy:
    Czy inicjalizacja tablicy wektorów przerwań jest zależna od typu mikrokontrolera? W literaturze i w poradnikach internetowych widzę, że wszędzie wektory mają jednakową inicjalizację: INT0addr to wszędzie INT0addr. Natomiast czytając dokumentację m8 widzę, że tablica zawiera jedynie skok do EXT_INT0. Co stosować w swoim kodzie, by prawidłowo zainicjować tablicę wektorów przerwań?

    Pozdrawiam i dziękuję za odpowiedzi ;)


    Tu się nie masz czym martwić. Wszystko kompilator załatwi.
    Procesor będzie się resetował jeśli ustawisz błędną nazwę dla obsługi przerwania lub o niej zapomnisz.
  • #6 14580929
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    tadzik85 napisał:
    Procesor będzie się resetował jeśli ustawisz błędną nazwę dla obsługi przerwania lub o niej zapomnisz.

    Małe wyjaśnienie tylko dodam - to nie będzie reset równy pinowi RESET, czy włączeniu zasilania, watchdog, itp., a jedynie skok do początku programu. Dlatego rejestry zostaną tak ustawione jak były.

    Warto to prześledzić na prostym programie:

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



    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #7 14580977
    Bartosz36
    Poziom 12  
    Posty: 91
    Pomógł: 3
    Ocena: 4
    tadzik85 napisał:
    Bartosz36 napisał:
    Czyli jeśli w kodzie C inicjuję jedynie wektor powiedzmy ADC_vect, to jedynie w kodzie asemblerowym jedynie .org ADCaddr będzie pozbawione komentarza <__bad_interrupt>.
    A propos wektorów i tablicy:
    Czy inicjalizacja tablicy wektorów przerwań jest zależna od typu mikrokontrolera? W literaturze i w poradnikach internetowych widzę, że wszędzie wektory mają jednakową inicjalizację: INT0addr to wszędzie INT0addr. Natomiast czytając dokumentację m8 widzę, że tablica zawiera jedynie skok do EXT_INT0. Co stosować w swoim kodzie, by prawidłowo zainicjować tablicę wektorów przerwań?

    Pozdrawiam i dziękuję za odpowiedzi ;)


    Tu się nie masz czym martwić. Wszystko kompilator załatwi.
    Procesor będzie się resetował jeśli ustawisz błędną nazwę dla obsługi przerwania lub o niej zapomnisz.


    Czyli pisząc w asemblerze mogę dowolnie nazywać wektory? Czy też kolega mnie źle zrozumiał?
  • #8 14581009
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Bartosz36 napisał:


    Czyli pisząc w asemblerze mogę dowolnie nazywać wektory? Czy też kolega mnie źle zrozumiał?


    Możesz, nikt ci w tym nie przeszkodzi. Po prostu zrobisz to co już w kompilatorze jest zrobione.
  • REKLAMA
  • #9 14581022
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    @Bartosz36 Tak, w asmeblerze możesz wektory nazwać dowolnie (podobnie jak w C, tu nazwę nie wymusza język, lecz konfiguracja linkera i bibliotek startowych C). Jedyne o co musisz zadbać to żeby odpowiedni wektor trafił pod odpowiedni adres.
    Przy okazji z ciekawości zapytam - po co chcesz robić wszystko w asemblerze? Sensowniejsza opcja to pisanie w C i jeśli to absolutnie niezbędne to umieścić wstawkę w asemblerze.
  • #10 14581102
    Bartosz36
    Poziom 12  
    Posty: 91
    Pomógł: 3
    Ocena: 4
    Jak zdefiniować adres, pod jaki trafia wektor? Szukałem w książkach jakie mam o asemblerze, ale jedyne co widzę to po prostu
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Co jest jedynie określeniem miejsca w pamięci. Tak, jakby "INT0addr" już przechowywało odpowiedni adres... Jak więc zdefiniować jaki to adres i upewnić się, że leci w prawidłowe miejsce?

    tmf napisał:
    Przy okazji z ciekawości zapytam - po co chcesz robić wszystko w asemblerze? Sensowniejsza opcja to pisanie w C i jeśli to absolutnie niezbędne to umieścić wstawkę w asemblerze.

    Do własnych projektów używam tylko C, tutaj niestety uczelnia narzuca język. No ale myślę, że czasem warto poznać też i inne języki. Chociaż używam C i tylko w nim piszę myślę, że dobrze jest wiedzieć co, jak działa i umieć coś więcej, poszerzać horyzonty ;)

    Dziękuję wszystkim za wyjaśnienia :)
    Pozdrawiam :D


    Patrzę teraz w dokumentację i widze, że mam już podane adresy wszystkich wektorów, więc czy inicjalizacja tablicy w postaci:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    będzie poprawna? Wydaje mi się że tak. Ale proszę o zweryfikowanie...
  • Pomocny post
    #11 14581164
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    Adres definiujesz właśnie tak jak pokazałeś - dyrektywą org. Symbol INT0addr to tylko symbol, któremu przypisana jest jakaś wartość. W asemblerze nie ma typów, więc wszystko zależy od programisty. Zdefiniujesz, że INT0addr ma np. 64, to .org INT0addr spowoduje, że następna instrukcja trafi pod adres 64.
    Co do języka - rozumiem, narzut to dobry powód :) Oczywiście assembler należy poznać, bez tego jak bez ręki, ale IMHO nie ma sensu robić całości w asm, no chyba, że promotor każe :)
  • #12 14581195
    Bartosz36
    Poziom 12  
    Posty: 91
    Pomógł: 3
    Ocena: 4
    No właśnie każe promotor, każe... :(

    Ostatnie pytanie:
    Czy zamiast reti, które powraca z przerwania ustawiając I, mogę napisać skok do samego przerwania, a na końcu jego obsługi wykonać powrót ze wskaźnikiem I? Widywałem też takie rozwiązania (poradniki w internecie) ale nie bardzo temu ufam.

    Doczytałem w książce:
    "W każdym elemencie tabeli wektorów przerwań należy umieścić instrukcję skoku bezwarunkowego w głąb programu do właściwej obsługi (lub użyć instrukcji reti, jeżeli w programie nie występuje obsługa przerwania)."

    Problem rozwiązany.

    Jeszcze raz dzięki wszystkim ;)
    Pozdrawiam

Podsumowanie tematu

✨ W dyskusji poruszono kwestie związane z obsługą przerwań w mikrokontrolerze ATmega8A, szczególnie w kontekście wektorów przerwań i ich inicjalizacji w asemblerze. Użytkownik zauważył, że większość wektorów wskazuje na __bad_interrupt, co sugeruje brak obsługi przerwań. Odpowiedzi wskazują, że kompilator automatycznie zarządza przerwaniami, a błędne nazwy mogą prowadzić do skoków do __bad_interrupt. Użytkownicy podkreślają, że inicjalizacja wektorów zależy od typu mikrokontrolera, a adresy wektorów można definiować za pomocą dyrektywy .org. Wskazano również, że zamiast instrukcji reti można użyć skoku do obsługi przerwania, ale należy to robić ostrożnie. Użytkownik dąży do zrozumienia, jak prawidłowo zainicjować tablicę wektorów przerwań oraz jak definiować adresy w asemblerze.
Wygenerowane przez model językowy.
REKLAMA