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

STM32F0 - Pętla while nie kończy się mimo dekrementacji timer_cnt do 0

uzi18 05 Mar 2015 20:24 909 11
REKLAMA
  • #1 14503806
    uzi18
    Poziom 24  
    Posty: 751
    Pomógł: 37
    Ocena: 82
    Witam,
    Bawie sie płytka STM32F0Discovery, napotkalem na dziwne zachwowanie prostej funkcji opozniajacej.
    Od razu mówie ze docelowo bedzie ona i tak uruchomiona na timerze, a to co ponizej traktuje jako swego rodzaju ciekawostke.

    Mianowicie zmienna timer_cnt schodzi do 0, a petla while sie nie chce zakonczyc.
    W tym czasie przerwania, DMA i Systick działa poprawnie.
    Moze moglby ktos sprawdzic jaki kod generuje inny kompilator?
    Czy to wogole wina kompilatora?

    Optymalizacja jako -O0

    Debugger stoi na "while", nie znam jeszcze assemblera na ten procesor.
    Prosilbym o jakis hint.

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


    wywołanie z main w taki sposob:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    Listing przed assemblerem:

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


    Kod: Bash
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 14503949
    m.ki
    Poziom 15  
    Posty: 117
    Pomógł: 13
    uzi18 napisał:

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


    Przydałby się kod tego przerwania, żebyśmy zobaczyli, jak timer_cnt jest zmniejszany.
    Może w ogóle nie jest zmniejszany?
    Może przerwanie jest wołane tak rzadko, że jeszcze nie zjechało z 1000 do zera?
    Może się przekręca przez zero i liczy dalej od MAX_INT?
    Może przerwanie jest w innym pliku i zmniejsza inną zmienną o tej samej nazwie?
    Może... chyba już dość się bawię ze szklaną kulą.

    Pozdrowienia,
    m.ki
  • REKLAMA
  • #3 14504005
    uzi18
    Poziom 24  
    Posty: 751
    Pomógł: 37
    Ocena: 82
    Tak jak napisalem, schodzi do 0 i stoi.
    Za to petla sie nie zakancza.

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


    W debugerze podgladalem zmienna wiec mam pewnosc ze schodzi do 0.

    Bez przesady z ta szklana kula.
  • #4 14504042
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Ano szklana.

    I niby co mamy z niej wywróżyć..

    Kod niekompletny ot cała odpowiedz na jaką możesz liczyć.
  • REKLAMA
  • #6 14504641
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Dopóki nie pokażesz całej obsługi tej zmiennej to nie da się pomóc :)
  • #7 14504758
    uzi18
    Poziom 24  
    Posty: 751
    Pomógł: 37
    Ocena: 82
    Tyle ze nic wiecej nie ma ... w programie zwiazanego z ta wlasnie zmienna.
    Sprawdzalem przed chwila jak wyglada kod przy optymalizacji -Os i tyle ze mniej obciazany jest stos.

    Generalnie wyglada na to ze sama funkcja jest ok i blad jest gdzies indziej ...
    Czy przed wejsciem do handlera systick jakies rejestry ida na stos?

    Widac np. ze przy optymalizacji -Os istnieje niebezpieczenstwo zamazania rejestru r3 ale w tym wypadku (-O0) nie powinno miec to miejsca.
  • REKLAMA
  • #8 14505021
    Piotr Piechota
    Poziom 22  
    Posty: 519
    Pomógł: 55
    Ocena: 85
    Wpisz do wnętrza pętli while(timer_cnt!=0); np. 'mruganie' portem żeby mieć pewność, że właśnie tam program się wykonuje.
  • #9 14505076
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    uzi18 napisał:
    Tyle ze nic wiecej nie ma ... w programie zwiazanego z ta wlasnie zmienna.
    Sprawdzalem przed chwila jak wyglada kod przy optymalizacji -Os i tyle ze mniej obciazany jest stos.

    Generalnie wyglada na to ze sama funkcja jest ok i blad jest gdzies indziej ...
    Czy przed wejsciem do handlera systick jakies rejestry ida na stos?

    Widac np. ze przy optymalizacji -Os istnieje niebezpieczenstwo zamazania rejestru r3 ale w tym wypadku (-O0) nie powinno miec to miejsca.



    Po co ta bezsensowna dywagacja o optymalizacjach i rejestrach?

    Pokaż kod inaczej na żadną pomoc nie licz.

    Na 100% błąd leży po twojej stronie.
  • #10 14505140
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Sprawdź czy program tak samo zachowuje się bez podłączonego debuggera.
  • #11 14505198
    uzi18
    Poziom 24  
    Posty: 751
    Pomógł: 37
    Ocena: 82
    Przyczepilem sie optymalizacji itp. opcji kompilatora ale w miedzyczasie wyszlo ze najwyrazniej rdzen zrzuca na stos rejestry r0-r3 i klika innych, wiec problem nie lezy tutaj.

    Wiem ze gdzies popelnilem blad, nie mam doswiadczenia z ARM-ami.
    Oczyszcze i zminimalizuje kod aby bylo absolutne minimum powodujace problemy i wrzuce.

    Systick szczesliwie miga diodami, wiec funkcjonuje.
    Delay na petli for tez dziwnie sie zachowuje albo trwa w nieskonczonosc albo nic nie trwa (podejrzewam ze tu pewnie optymalizator miesza).

    Ciekawostka jest taka ze jak sie wstawi breakpointa na fragment w assemblerze po przypisaniu, gdzie jest
    wczytywan wartosc na porownanie do 0 i skok na poczatek wczytywania jesli nie rowne, to ...
    wynik porowania jest ok i wychodzi z while (przechodze przez wszystkie linijki w trybie Instruction List, tj. wykonuje sie kod maszynowy).
    Bez debugowania i debugowanie zgodnie z linijkami kodu w "c" niestety nie wyskakuje.

    Zminimalizuje kod do minimum i zobaczymy moze cos wyjdzie przy okazji.
  • #12 14507704
    uzi18
    Poziom 24  
    Posty: 751
    Pomógł: 37
    Ocena: 82
    Panowie, problem rozwiazany, poniewaz poczatkowo korzystalem tylko z przerwan (glownie systick) miałem ustawioną maske SCB_SCR_SLEEPONEXIT_Msk w SCB->SCR.

    Gdy zaczalem wrzucac do main() co rusz to cos wiecej, pierwsze wywołanie handler-a Systick zatrzymywało wykonywanie funkcji która została przerwana.
    Debugger omijal to ograniczenie.

    Dotarlem do tego poprzez okrajanie kodu do minimum.

    Dziekuje wszystkim za pomoc.

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik napotkał problem z funkcją opóźniającą na płytce STM32F0Discovery, gdzie pętla while nie kończy się mimo dekrementacji zmiennej timer_cnt do zera. W trakcie dyskusji zasugerowano sprawdzenie kodu przerwania, które zmienia timer_cnt, oraz weryfikację, czy zmienna jest poprawnie dekrementowana. Użytkownik potwierdził, że timer_cnt schodzi do zera, ale pętla nie kończy się. Po dalszym badaniu okazało się, że problem wynikał z ustawienia maski SCB_SCR_SLEEPONEXIT_Msk, co powodowało zatrzymanie wykonywania funkcji po pierwszym wywołaniu handlera Systick. Po usunięciu tego ustawienia problem został rozwiązany.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA