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.

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

Bartosz36 01 Kwi 2015 20:25 690 11
  • #1 01 Kwi 2015 20:25
    Bartosz36
    Poziom 12  

    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: asm
    Zaloguj się, aby zobaczyć kod


    Proszę o wytłumaczenie, dlaczego tak się dzieje... czy nie powinno to wyglądać nieco inaczej?

    0 11
  • #2 01 Kwi 2015 20:26
    tadzik85
    Poziom 38  

    Do przemyślenia, co miałoby się stać gdybyś miał włączone przerwanie ale nie miał jego obsługi?

    0
  • Pomocny post
    #3 01 Kwi 2015 20:48
    dondu
    Moderator Mikrokontrolery Projektowanie

    Do tego co napisał tadzik85 zauważ, że wszystkie rozkazy skoku wskazują na __bad_interrupt, który wygląda np. tak:

    Kod: asm
    Zaloguj się, aby zobaczyć kod

    a jak to działa zrozumiesz analizując swój plik lss.

    0
  • #4 01 Kwi 2015 21:00
    Bartosz36
    Poziom 12  

    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 ;)

    0
  • #5 01 Kwi 2015 21:02
    tadzik85
    Poziom 38  

    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.

    0
  • #6 01 Kwi 2015 21:12
    dondu
    Moderator Mikrokontrolery Projektowanie

    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
    Zaloguj się, aby zobaczyć kod



    Kod: asm
    Zaloguj się, aby zobaczyć kod

    0
  • #7 01 Kwi 2015 21:23
    Bartosz36
    Poziom 12  

    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ł?

    0
  • #8 01 Kwi 2015 21:28
    tadzik85
    Poziom 38  

    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.

    0
  • #9 01 Kwi 2015 21:30
    tmf
    Moderator Mikrokontrolery Projektowanie

    @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.

    1
  • #10 01 Kwi 2015 21:47
    Bartosz36
    Poziom 12  

    Jak zdefiniować adres, pod jaki trafia wektor? Szukałem w książkach jakie mam o asemblerze, ale jedyne co widzę to po prostu

    Kod: asm
    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: asm
    Zaloguj się, aby zobaczyć kod

    będzie poprawna? Wydaje mi się że tak. Ale proszę o zweryfikowanie...

    0
  • Pomocny post
    #11 01 Kwi 2015 22:00
    tmf
    Moderator Mikrokontrolery Projektowanie

    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 :)

    0
  • #12 01 Kwi 2015 22:05
    Bartosz36
    Poziom 12  

    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

    0