Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32F2] Kasowanie flagi przerwania periodycznego

08 Lis 2011 21:26 2101 7
  • Poziom 11  
    Witam!
    Timer generuje przerwanie periodyczne. W procedurze obsługi testowo chciałem przełączać stan na jednej z linii portu GPIO (prymitywny debug na LED), ale... okazało się, że nie działa. W pierwszej chwili szukałem błędów w inicjalizacji timera, ale później się okazało, że przerwania się generują, tylko ja tego nie widzę, bo nie wykonuje się przełączenie bitu portu.
    Niżej załączyłem przykłady.
    W pierwszym przykładzie stan linii portu nie zmienia się, a w drugim tak. Różnica polega na miejscu wstawienia instrukcji kasowania flagi zgłoszenia przerwania.
    Przykład 1:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Przykład 2:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Dodatkowo, wystarczy do pierwszego niedziałającego przykładu dodać po ostatnim wierszu 2 NOPy i ten też zaczyna działać.
    W NVIC jedynie włączyłem przerwanie, niczego więcej nie zmieniałem.
    Dlaczego tak się dzieje?
    Jakiś prefetch daje o sobie znać?
    Czy jest możliwe 2-krotne wykonanie procedury obsługi? (2-krotne toggle mogło by dać podobny efekt)
    Jak z tym żyć? ;)

    Edit:
    To poczekam na wróżkę do jutra. ;-) (żart)

    Już zdążyłem się upewnić, że jeśli kasowanie żądania jest na samym końcu procedury, to procedura obsługi wykonuje się 2 razy. Właściwie nie potrzeba tu dodatkowego kodu, bo pytanie dotyczy raczej wewnętrznych mechanizmów działania procesora, których chyba do końca jeszcze nie rozumiem, ale Freddiemu się nie odmawia. :)

    Inicjacja timera:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Program główny:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Uruchomienie PLL:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    A pliki startowe są od Freddiego, z moimi modyfikacjami dla STM32F2xx (głównie wektory).
    Bawiłem się też z z tym rozdwojonym stosem. Nie ma tu żadnych systemów operacyjnych, aplikacji użytkownika itp. itd., więc przywróciłem naturalny porządek rzeczy, czyli tylko główny stos MSP, a PSP wyłączony i jego rozmiar wyzerowany. Jednak nie dało to nic, ani niczego nie zmieniło.
    Darmowe szkolenie: Ethernet w przemyśle dziś i jutro. Zarejestruj się za darmo.
  • Specjalista - Mikrokontrolery
  • Poziom 22  
    Sprawdz czy kasowanie wszystkich flag dla TIM2 zmieni sytuację....
  • Poziom 11  
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Nic nie zmienia.
    Nadal, jeśli jest na końcu procedury, to jest źle, a jak wcześniej, albo 2 nopy przed końcem, to OK.
  • Poziom 22  
    To kod, który u mnie na STMF107 działa - może znajdziesz jakieś róznice...
    W przerwaniu mam obsługę klawiatury 4x4 + kilka liczników, ale to tutaj nieistotne, więc nie zamieszczam.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Tez miałem mały problem z uruchomieniem tego przerwania, a bład tkwił w deklaracji stosu w pliku LD, który był ustawiony na 0 (przykład od Freddiego)...

    Edit: Na forum o STM32 znalazłem bardzo podobny wątek, a w nim piszą:

    "Remember this is a pipelined processor - if you're exiting your interrupt service routine immediately after clearing the IRQ bit, the bit clear operation might not have had sufficient time to propagate through. Try putting:
    while (TIM7->SR != 0x0);
    or similar at the end of your interrupt service routine.

    Or alternatively, put the line:

    TIM7->SR = 0x0;

    at the beginning of your interrupt service routine instead of at the end."

    To by chyba wyjasniało ten problem....?
  • Poziom 11  
    Nie zauważyłem żadnych istotnych różnic w konfiguracji Twojego timera. Jak widzę, kasowanie flag też masz na końcu procedury obsługi.

    Właśnie przetestowałem u mnie:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    że kasowanie flagi na końcu procedury, a po nim jeszcze sprawdzenie, czy flaga się skasowała działa, ale równie dobrze sprawdzają się 2 NOPy na końcu. :)

    U Ciebie na STM32F1xx nie ma problemów, ale ja mam proca STM32F2xx, w którym CPU i NVIC są sporo szybsze, bo taktowane 120MHz (u Ciebie 72MHz), a zegar moich peryferiów to 60MHz (u Ciebie 72MHz). Jak sądzę szybsza CPU i NVIC oraz na domiar złego nieco wolniejsze peryferia i APB uwypuklają problem, którego u Ciebie nie widać, a u mnie już daje o sobie znać.
    To zapewne wynika z tego, że zanim dokona się zapis w peryferium, a następnie to peryferium zdejmie sygnał zgłaszający przerwanie z NVIC, mija jakiś czas, w którym procesor zdąży już wyjść z obsługi przerwania, a NVIC na nowo zaliczy nieskasowane jeszcze zgłoszenie.

    Chyba nie ma na to rady, tylko o tym pamiętać i albo kasować flagi przerwań na początku procedury, albo na końcu i dodawać jeszcze opóźnienie (czy to 2 NOPy, czy sprawdzenie skasowania).

    Dzięki i pozdrawiam!
  • Poziom 22  
    Przy okazji wspólnego poszukiwania rozwiązania i ja się czegoś nauczyłem :-)

    Swoją drogą to ciekawe, czy podobny problem występuje i w innych rodzinach procesorów (innych producentów) czy jest to tylko cecha STM'ów?

    Pozdrawiam :-)
  • Poziom 11  
    Niedawno programowałem LPC2478 i tam nie było tego problemu.
    No ale to już niemłody ARM7TDMI-S, a nie Cortex-M3. :)