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.

[attiny13][C++][atmel studio6] - wieszanie sie atmel studio podczas debugowania

_Magus_ 27 Gru 2014 23:08 1257 11
  • #1 27 Gru 2014 23:08
    _Magus_
    Poziom 9  

    Witam,

    Piszę program na ATtiny13A, aby działał jak licznik mod 4 (piny PB0 i PB1), zmiana wyzwalana zboczem opadającym na PB3.
    Rozwiązanie opiera się na przerwaniach.
    PCINT3 to obsługa "przycisku" -> naciśnięcie powoduje uruchomienie timera (ustawienie adekwatnego przerwania).
    Obsługa przerwania timera zwiększa licznik przepełnień - po ok2 sek wyłącza układ.
    Wyłączenie przycisku powoduje sprawdzenie, jak długo był włączony, a następnie zwiększenie licznika (z aktualizacją portu) oraz wyłączenie przerwań timera.

    Niestety gdy próbuje włączyć debug kodu to AtmelStudio wiesza się na funkcji sei().
    Mam ustawione breakpointy w obsłudze obu przerwań, ale nigdy tam się nie zatrzymuje. Jedyny ratunek to zabicie procesu, aby zamknąć studio.

    Co robię nie tak?

    kod:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0 11
  • #4 28 Gru 2014 05:07
    435758
    Użytkownik usunął konto  
  • #5 28 Gru 2014 17:17
    _Magus_
    Poziom 9  

    Dzięki za odzew :)

    Odpowiadam po kolei:

    - debugger - odpalam wbudowany symulator
    - sleep_mode - nie wejdzie w obslugę TIM0_OVF, to przerwanie włączone zostaje po naciśnięciu przycisku
    - sugerowana zmiana ustawień nie poprawiła sytuacji ...

    Jednak udało mi się rozwiązać problem.
    Miałem breakpoint ustawiony w linii:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Zmieniłem kod na

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Teraz wszystko działa, jak powinno i studio się nie wiesza.
    A dlaczego tak się dzieje to mogę tylko przypuszczać wpływ optymalizacji kodu.

    pozdrawiam

    0
  • #6 28 Gru 2014 17:35
    dondu
    Moderator Mikrokontrolery Projektowanie

    _Magus_ napisał:
    - sleep_mode - nie wejdzie w obslugę TIM0_OVF, to przerwanie włączone zostaje po naciśnięciu przycisku

    Nie rozumiem tego zdania, ale zastanów się jeszcze raz nad tym fragmentem Twojego programu, który pokazałem w poprzednim poście.

    _Magus_ napisał:
    Teraz wszystko działa, jak powinno i studio się nie wiesza.
    A dlaczego tak się dzieje to mogę tylko przypuszczać wpływ optymalizacji kodu.

    Jaką optymalizację masz wybraną?

    BTW: W kolejnych projektach definiuj F_CPU w kodzie programu z tych powodów: http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html

    0
  • #7 28 Gru 2014 18:25
    _Magus_
    Poziom 9  

    dondu napisał:

    Nie rozumiem tego zdania,


    Aby dojść do sleep_mode(), musi wejść do obsługi przerwania, które zostaje włączone dopiero po naciśnięciu przycisku.

    dondu napisał:

    ale zastanów się jeszcze raz nad tym fragmentem Twojego programu, który pokazałem w poprzednim poście.


    Nie bardzo rozumiem na co mam zwrócić uwagę...

    Swoją drogą, czy da się debugować kod, który ma w sobie usypianie/wyłączanie układu?
    W swoim kodzie założyłem, że po wyłączeniu jednostki, naciśnięcie przycisku ponownie go włączy - czy tak będzie w istocie?

    dondu napisał:

    Jaką optymalizację masz wybraną?

    Standardowa. Musiałbym zbadać kod po kompilacji, aby stwierdzić przyczynę ewentualnego "niewidzenia" breakpointów.

    dondu napisał:

    BTW: W kolejnych projektach definiuj F_CPU w kodzie programu...


    Jak widać w moim kodzie, F_CPU jest zdefiniowane. Chyba, że #define to za mało i trzeba coś jeszcze?

    dzięki!

    0
  • #8 28 Gru 2014 18:40
    dondu
    Moderator Mikrokontrolery Projektowanie

    _Magus_ napisał:
    Nie bardzo rozumiem na co mam zwrócić uwagę...

    Przeanalizuj dokładnie co robi funkcja sleep_mode() (zobacz jej definicję) w kontekście umieszczenia jej w tak zadeklarowanej funkcji obsługi przerwania, przy zawartości tej funkcji którą pokazałeś. To bardzo istotne dla Twojego projektu ponieważ:

    _Magus_ napisał:
    W swoim kodzie założyłem, że po wyłączeniu jednostki, naciśnięcie przycisku ponownie go włączy - czy tak będzie w istocie?

    ... tak się nie stanie.

    mała podpowiedź:

    Cytat:
    The I-bit is cleared by hardware after an interrupt has occurred, ...
    If the Global Interrupt Enable Register is cleared, none of the interrupts are enabled independent of the individual interrupt enable settings.



    _Magus_ napisał:
    Standardowa. Musiałbym zbadać kod po kompilacji, aby stwierdzić przyczynę ewentualnego "niewidzenia" breakpointów.

    Standardowa, czyli jaka konkretnie?


    _Magus_ napisał:
    dondu napisał:

    BTW: W kolejnych projektach definiuj F_CPU w kodzie programu...

    Jak widać w moim kodzie, F_CPU jest zdefiniowane. Chyba, że #define to za mało i trzeba coś jeszcze?

    Poświęć czas na przeanalizowanie materiału, który Ci wskazałem z dopiskiem, byś robił to w kolejnych projektach, bo w tym na razie nie ma to znaczenia, ale gdy go rozbudujesz, to możesz się zdziwić, dlaczego nie działa prawidłowo.

    0
  • #9 28 Gru 2014 18:48
    tmf
    Moderator Mikrokontrolery Projektowanie

    A propos tych breakpointów - AS z pewnością zaznaczył, że breakpoint jest nieaktywny - ze względu na optymalizację nie w każdym miejscu da się go założyć. W takiej sytuacji wystarczy przejść w okno disasemblera i tam założyć breakpointa - to zawsze zadziała. Poza tym AS z pewnością się nie zawiesił, po prostu symulował program, który się nie przerywał. Ale można go było przerwać klikając na przycisk przerwania lub zatrzymania symulacji.

    0
  • #10 28 Gru 2014 21:20
    _Magus_
    Poziom 9  

    Poczytałem o usypianiu.

    Faktycznie mój obecny kod nie zadziała zgodnie z moimi założeniami.
    Przerwania muszą być aktywne przed uśpieniem procka.

    Czy dobrze mi się wydaje, że wystarczy wrzucić sleep_mode() do pętli while(1) ?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    put_to_sleep ustawiony na 1 w obsłudze przerwania, tam gdzie poprzednio bylo wywołanie sleep_mode().

    Dodano po 3 [minuty]:

    tmf napisał:
    A propos tych breakpointów - AS z pewnością zaznaczył, że breakpoint jest nieaktywny - ze względu na optymalizację nie w każdym miejscu da się go założyć. W takiej sytuacji wystarczy przejść w okno disasemblera i tam założyć breakpointa - to zawsze zadziała. Poza tym AS z pewnością się nie zawiesił, po prostu symulował program, który się nie przerywał. Ale można go było przerwać klikając na przycisk przerwania lub zatrzymania symulacji.


    "wieszanie", które zaobserwowałem polegało na tym, że gdy puszcze działanie programu w trybie debug, a potem nacisnę stop (kwadracik) to po 1 min wyskakuje okienko z pytaniem czy czekać kolejną minute, czy przerwać czekanie. jednak niezależnie co wybiorę - nie odzyskuję kontroli nad AS.

    0
  • #11 28 Gru 2014 21:21
    dondu
    Moderator Mikrokontrolery Projektowanie

    _Magus_ napisał:
    Czy dobrze mi się wydaje, że wystarczy wrzucić sleep_mode() do pętli while(1) ?

    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    put_to_sleep ustawiony na 1 w obsłudze przerwania, tam gdzie poprzednio bylo wywołanie sleep_mode().

    Tak to dobry sposób (jeśli masz na myśli pętlę główną poza przerwaniem), tylko nie zapomnij o volatile dla put_to_sleep.

    0
  • #12 29 Sty 2015 19:02
    _Magus_
    Poziom 9  

    Czas zamknąć wątek.

    Rozwiązanie opisane w poście #5

    Dziękuję za porady i udział w dyskusji!

    0