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

[AVR-ATmega88PA] Powrót do funkcji main - czy to przepełnienie stosu?

m471 29 Kwi 2020 21:52 594 11
  • #1 18657406
    m471
    Poziom 5  
    Witam

    Podczas debugowania atmegi88pa natknąłem się na dziwny problem, program działa normalnie i nagle wraca do pierwszej linii w funkcji main(). Nie resetuje się, wszystkie rejestry i zmienne są ustawione i zdefiniowane.
    Czy to może być przepełnienie stosu? Jeśli tak to jak to sprawdzić i naprawić?

    Debuguje za pomocą ATMEL-ICE w AtmelStudio, kod jest dość długi więc wyślę w razie konieczności, być może to elementarny problem.

    Pozdrawiam :)
  • #2 18657441
    roberto.pi
    Poziom 12  
    Jesli zmienne są ok to efekt taki może wywołać optymalizator (pozorne wykonanie czegoś co wynikać się nie powinno). Wyłącz na próbę optymalizację i sprawdź.
  • #3 18657443
    tmf
    VIP Zasłużony dla elektroda
    m471 napisał:
    Podczas debugowania atmegi88pa natknąłem się na dziwny problem, program działa normalnie i nagle wraca do pierwszej linii w funkcji main()

    To chyba jednak się resetuje. Ustaw sobie breakpointa w kodzie przed maim, będziesz wiedział czy procek przez niego przechodzi. Z jaką optymalizacją debugujesz? Przejdź na O1 i sprawdź czy problem się powtarza. Czasami pozornie procesor skacze dziwnie po kodzie, ale wynika to wyłącznie z pracy optymalizatora. Warto też się przełączyć na widok asemblera i tam sprawdzić w jakim fragmencie kodu jesteś.
  • #4 18657540
    m471
    Poziom 5  
    roberto.pi napisał:
    Jesli zmienne są ok to efekt taki może wywołać optymalizator (pozorne wykonanie czegoś co wynikać się nie powinno). Wyłącz na próbę optymalizację i sprawdź.


    Debuguje na wyłączonej optymalizacji
  • #6 18657567
    m471
    Poziom 5  
    tmf napisał:
    m471 napisał:
    Podczas debugowania atmegi88pa natknąłem się na dziwny problem, program działa normalnie i nagle wraca do pierwszej linii w funkcji main()

    To chyba jednak się resetuje. Ustaw sobie breakpointa w kodzie przed maim, będziesz wiedział czy procek przez niego przechodzi. Z jaką optymalizacją debugujesz? Przejdź na O1 i sprawdź czy problem się powtarza. Czasami pozornie procesor skacze dziwnie po kodzie, ale wynika to wyłącznie z pracy optymalizatora. Warto też się przełączyć na widok asemblera i tam sprawdzić w jakim fragmencie kodu jesteś.


    Jestem na O0, breakpointy mam w pierwszych liniach main, program działa tak:
    >wykonuje kilka instrukcji
    >wraca do 1 linii
    >działa normalnie
    >wchodzi w pętlę główną
    >wykonuje kilka instrukcji
    i już w kółko
    >wraca do pierwszej linii
    >wykonuje kilka instrukcji

    Kiedyś podobny problem (choć nie miałem jeszcze debuggera więc nie wiem czy to był restart czy to co teraz) wynikał z zainicjowania w timerze tylko ICR1H, po zainicjowaniu ICR1L=0 wszystko hulało, teraz rozkładam ręce. Stos raczej nie jest przepełniony, w pamięci IRAM jest dużo wolnego miejsca. Jedyne co jeszcze mi przychodzi do głowy, to wadliwy lub zużyty model

    Dodano po 1 [minuty]:

    JarekC napisał:
    Czy używasz WatchDoga czy go przypadkiem nie włączyłeś na stałe (FuseBits)?
    Możesz odczytać stan rejestru MCUSR aby sprawdzić co było przyczyną resetu.


    Jak kolega wyżej napisał, nie jest to do końca reset, MCUSR=0, WatchDog wyłączony
  • #7 18657625
    JarekC
    Poziom 32  
    Może masz gdzieś błąd typu np przekroczenie indeksu tablicy i niszczysz zawartość stosu.
    Może wtedy wystąpić sytuacja że nastąpi powrót do miejsca gdzie nie ma twojego kodu (już samy FFFF = SBRS R31,7)
    Procesor będzie wkonywał kod do końca pamięci aż wróci do adresu 0.
  • Pomocny post
    #8 18658022
    roberto.pi
    Poziom 12  
    JarekC napisał:
    Może masz gdzieś błąd typu np przekroczenie indeksu tablicy i niszczysz zawartość stosu.
    Może wtedy wystąpić sytuacja że nastąpi powrót do miejsca gdzie nie ma twojego kodu (już samy FFFF = SBRS R31,7)
    Procesor będzie wkonywał kod do końca pamięci aż wróci do adresu 0.

    Ale wtedy wykona się ustawianie zmiennych.

    Dodano po 1 [minuty]:

    chyba, że rozumieć
    m471 napisał:
    wszystkie rejestry i zmienne są ustawione i zdefiniowane.

    w ten sposób, ze są ustawiane jak po resecie. W takiej sytuacji należy sprawdzić przyczynę resetu, może BOD?
  • Pomocny post
    #10 18658176
    tmf
    VIP Zasłużony dla elektroda
    m471 napisał:
    Jestem na O0, breakpointy mam w pierwszych liniach main, program działa tak:

    Przede wszystkim przejdź do widoku asemblera i tam zobacz jak wygląda wykonywanie programu. Breakpointy też postaw na instrukcjach asemblera, przed main. Czasami informacje o debugowaniu, pomiędzy C a asemblerem się rozjeżdżają, chociaż dla O0 nie powinno mieć to miejsca.
    Jest możliwe, że tak jak piszą koledzy coś nadpisuje stos, może masz jakieś nieobsłużone przerwanie, bez handlera?
  • #11 18659271
    m471
    Poziom 5  
    tmf napisał:
    m471 napisał:
    Jestem na O0, breakpointy mam w pierwszych liniach main, program działa tak:

    Przede wszystkim przejdź do widoku asemblera i tam zobacz jak wygląda wykonywanie programu. Breakpointy też postaw na instrukcjach asemblera, przed main. Czasami informacje o debugowaniu, pomiędzy C a asemblerem się rozjeżdżają, chociaż dla O0 nie powinno mieć to miejsca.
    Jest możliwe, że tak jak piszą koledzy coś nadpisuje stos, może masz jakieś nieobsłużone przerwanie, bez handlera?


    Problem rozwiązany, okazało się że włączyłem przerwania PCINT a ich funkcję dałem do komentarza, w celu późniejszej realizacji. Bardzo dziękuję wszystkim za pomoc. Temat do zamknięcia.
    Pozdrawiam :)
  • #12 18659284
    roberto.pi
    Poziom 12  
    m471 napisał:
    okazało się że włączyłem przerwania PCINT a ich funkcję dałem do komentarza, w celu późniejszej realizacji.

    Na to jest sposób ISR( ISR_BAD)

Podsumowanie tematu

Podczas debugowania mikrokontrolera AVR ATmega88PA użytkownik napotkał problem, w którym program nieoczekiwanie wraca do pierwszej linii funkcji main, mimo że nie występuje reset. Użytkownik podejrzewał przepełnienie stosu, jednak po analizie okazało się, że problem wynikał z włączenia przerwań PCINT, które były skomentowane w kodzie. Uczestnicy dyskusji sugerowali różne przyczyny, takie jak błędy w indeksowaniu tablic, nieobsłużone przerwania, oraz wpływ optymalizacji kompilatora. Ostatecznie problem został rozwiązany przez wyłączenie nieaktywnych przerwań.
Podsumowanie wygenerowane przez model językowy.
REKLAMA