Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Computer ControlsComputer Controls
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[STM32][C/GCC] Przerwanie na buttonie i Hard Fault

qscgu 07 Feb 2012 22:45 5758 48
  • #31
    qscgu
    Level 34  
    Ogólnie rzecz biorąc udało mi się skonfigurować buttona tak, żeby działał na przerwaniach i timerze. Ale coś zaś musiałem fundamentalnego skopać i wywala HardFault. Tym razem nie mogę uruchomić SysTicka.

    Code: c
    Log in, to see the code


    W system init jest gpio init. A w nim:

    Code: c
    Log in, to see the code


    No i obsługa ticka:
    Code: c_loadrunner
    Log in, to see the code


    Nic więcej w zasadzie nie ma. Zastanawiam się, czy przy zmianie jakichś rejestrów nie muszę chwilę odczekać?
  • Computer ControlsComputer Controls
  • #32
    gaskoin
    Level 38  
    Pokaż Twój makefile i skrypt linkera
  • #33
    qscgu
    Level 34  
    Ok, coś jest nie tak.

    Przede wszystkim systick działa na trybie optymalizacji O1 i O2. Bez zmiany kodu.

    Na O0 od razu jest hard fault. Ale nie występuje na żadnej linijce kodu. Nie wchodzi do przerwania i wywala od razu błąd. EDIT: Działa w momencie kiedy wywaliłem inicjalizacje:
    NVIC_Init(&NVIC_InitStructure);
    A w to miejsce dałem:
    NVIC->ISER[EXTI0_IRQn >> 0x05] = 1 << EXTI0_IRQn;

    Ale sytuacja jest taka sama jak w przypadku O1/O2, czyli:

    Włączyłem O2. Musiałem przy tym zaktualizować bibliotekę core_cm3.h i .c ale niestety przerwania nie działają. Wchodzi i skacze po nich i już z nich nie wychodzi!

    Code: c
    Log in, to see the code


    Natomiast w trybie O0 błąd Hard Fault występuje tuż po konfiguracji NVIC dla buttona:

    Code: c
    Log in, to see the code


    Dokładnie na tej linijce:
    Code: c
    Log in, to see the code

    Wewnątrz procedury NVIC_Init.

    Mój makefile. Poza optymalizacją i kodem procesora niczego nie ruszałem.

    Code: c
    Log in, to see the code


    skrypt linkera:
    Code: c
    Log in, to see the code



    Zdaje sobię sprawę, że to jest do wersji 128K-20K ale mimo wszystko taki mały programik nie powinien wyjść poza te wartości. No i wcześniej to działało...
  • Computer ControlsComputer Controls
  • Helpful post
    #34
    Freddie Chopin
    MCUs specialist
  • #35
    qscgu
    Level 34  
    Nie ma takiej funkcji w misc.c.
    Zresztą zobacz, że problem już nie występuje z hard fault. Natomiast wchodzi cały czas w procedury obsługi przerwania. Nie wychodzi z nich.
  • #36
    nsvinc
    Level 35  
    Skoro hardfault występuje przy kompilacji z -O0 to znaczy że jednak występuje, a ty tylko znalazłeś obejście problemu.

    Flagi przerwan w EXTI trzeba gasić ręcznie. Jesli tego nie zrobisz, będziesz w stanie permanentnego przerwania...
  • #37
    Freddie Chopin
    MCUs specialist
  • #38
    qscgu
    Level 34  
    Ok po kolei bo widać trochę zamieszałem.

    Zarówno w kofiguracji O0, O1, O2, Os występuje ten sam problem.

    Wchodzi cały czas do funkcji obsługi przerwań. Hard fault przestał występować po aktualizacji biblioteki core_cm3.h i c.

    Moje inicjalizacje wyglądają następująco:

    Code: c
    Log in, to see the code


    Sukcesywnie pozbywam się funkcji obsługi z bibliotek STM32. Robie to w taki sposób, że podpatruje co jest w oryginalnej funkcji. Konfrontuje to z tym co znajdę w internecie (głównie tutaj na elektrodzie i zazwyczaj sugeruje się wypowiedziami Freddiego.)

    W funkcji main:
    Code: c_loadrunner
    Log in, to see the code


    Program działa następująco przy wyłączonym debugowaniu:
    Dioda 1 miga - przerwanie systemowe
    Dioda 2 miga - główna pętla programu
    Diody 3 i 4 migają bardzo szybko, ale da się to zauważyć. obie te diody są togglowane są w funkcjach obsługi obu przerwań:

    Code: c_loadrunner
    Log in, to see the code


    W momencie naciśnięcia przycisku i jego przytrzymania diody zatrzymują się. Czyli dzieje się to dokładnie na odwrót jak chce.
    Przycisk wciśnięty -> Nie ma przerwania żadnego.
    Przycisk normalnie -> Generuje się milion przerwań.[/code]
  • #39
    qscgu
    Level 34  
    Odpowiem sobie sam na to pytanie. Otóż funkcja Freddiego nie zupełnie działa poprawnie:

    Zamiast
    Code: c
    Log in, to see the code

    Wstawiłem oryginalną:
    Code: c_loadrunner
    Log in, to see the code

    I działa.

    Nie wiem dlaczego takie problemy. Może jakiś błąd w funkcji gpio_pin_cfg ?

    Jeśli nikt nic nie doda to zamknę wątek jako rozwiązany.
    Podsumując:
    trzeba się upewnić, że mamy najnowszego cmsysa.
    Najlepiej olać biblioteki od stma. Skopiować co potrzeba, zoptymalizować i resztę wywalić.
  • #40
    Freddie Chopin
    MCUs specialist
    Nie wiem czy wiesz, ale moja funkcja oczekuje NUMERU pinu (0, 1, 2, ...), natomiast Ty jej przekazujesz MASKĘ pinu (1 << 0, 1 << 1, 1 << 2, ...). Innymi słowy konfigurujesz (w tym akurat przypadku) pin nr 1 (1 << 0 == 1), a nie pin nr 0.

    Tak więc zanim zaczniesz sugerować że ktoś ma błąd sprawdź najpierw czy nie zrobiłeś go Ty.

    BTW - W przykładach jest najnowszy CMSIS tyle że w wersji 1.x, dostępna jest już wersja 2.x, jednak obecnie obydwie te "gałęzie" rozwijane są równocześnie.

    4\/3!!
  • #41
    qscgu
    Level 34  
    Faktycznie.
    Znaczy się:
    Wiedziałem że twoja funkcja bierze numer pinu, ale myślałem że dla 0 pinu nie ma to znaczenia bo wartość będzie wynosić 0. Myliłem się. Pin_0 to jest 1 a nie 0.

    Sprawdziłem teraz, faktycznie, twoja funkcja działa, zwracam honor.

    Co do CMSISa to fakty są takie:
    1.2 i 1.3 -> Hard Fault w losowym momencie
    2.X -> brak problemów.
  • #42
    Freddie Chopin
    MCUs specialist
    Nie wiem jaki wpływ na to mógłby mieć CMSIS... W samym CMSISie jest generalnie tylko kilka definicji, np NVIC_EnableIRQ().

    Musiałbyś wrzucić tu cały swój problematyczny projekt w wersji "złej".

    4\/3!!
  • #43
    qscgu
    Level 34  
    Nic nie zmieniałem od tego czasu. Jakieś tam pierdółki. Ale na 100% to byłą wina CMSISa.

    Wcześniej Hard fault latał na prawo i lewo. Od czasu zmiany na nową wersję nie było już żadnego problemu. A udało mi się uruchomić ADC i DAC'a od tego czasu.

    Wcześniej dla O0 nie było błędu kompilacji natomiast dla O1 i O2 były. Przeczytaj wcześniejsze posty tam wszystko jest opisane jak się to zachowywało. Teraz nie ma problemu dla żadnego stopnia optymalizacji.

    Aha problem prawdopodobnie występował z definicjami assemblera. Zobacz jakie błędy wywalał wczesniej.
  • #44
    Freddie Chopin
    MCUs specialist
    Błędy jakie otrzymujesz (log konsoli) pokazałeś tylko raz. Co do błędów assemblera, to zapewne chodziło Ci o to co opisane zostało przy końcu tej strony http://www.freddiechopin.info/index.php/pl/ar...tm32f10x-standard-peripherals-library?start=4 to nie wiem jak to miałoby mieć coś wspólnego z Twoim problemem...

    Na 99% problem masz gdzie indziej i albo rozwiązałeś go przypadkiem, albo ominąłeś go tymczasowo.

    4\/3!!
  • #45
    qscgu
    Level 34  
    Zrobiłem tak:

    Błąd występował. Hard Fault.
    1. Włączyłem optymalizacje O1.
    2. Próbowałem kompilować. Błędy "registers may not be the same"
    3. Poczytałem o tych błędach w necie i znalazłem jakieś tam niby podmianki do tych funkcji.
    4. Nic one nie dały. Teraz błędu nie było "registers may not be the same" ALE wywalało błąd Hard fault przy wszystkich optymalizacjach.
    5. Znalazłem nową wersję CMSIS i podmieniłem. Brakowało również z nich:
    #include "core_cmInstr.h" /*!< Core Instruction Access */
    #include "core_cmFunc.h" /*!< Core Function Access */
    6. Ściągnąłem i dodałem
    7. Problem ustał. Wszystkie optymalizacje działały, nigdy więcej już nie widziałem błędu hard fault.

    Potem miałem problem z tą twoją funkcja ale to już dalszy ciąg opowieści znasz. Nie mniej jednak OD momentu kiedy OSTATNI raz widziałem hard fault DO momentu kiedy zaaktualizowałem CMSISa NIE DOTKNĄŁEM kodu źródłowego. Dla mnie jednoznacznie problemem był starszy CMSIS.

    Zresztą, teraz wypisuje głupoty bawie się rejestrami i czasem zdarzy mi się coś źle zrobić i widzę to w debugu ale nie wywala hard faulta.
  • #47
    qscgu
    Level 34  
    Innego racjonalnego wytłumaczenia nie mogę znaleźć. Wcześniej kolejność konfiguracji portów miała znaczenie teraz już nie. Zamieniam instrukcje miejscami i działa.

    Wcześniej myślałem, że po prostu arm tak już ma ale się myliłem. Nie wywala błędów nawet przy konfiguracji na czuja. (Po prostu nie działa jak coś).

    Mógłbym się jeszcze dowiedzieć jak skonfigurować skrypt linkera pod mój proc?

    Mam obecnie tak:
    Code:

    __main_stack_size = 1024;
    __process_stack_size = 1024;

    MEMORY
    {
       rom (rx)   : org = 0x08000000, len = 128k
       ram (rwx)   : org = 0x20000000, len = 20k
    }


    Myślę żeby zmienić na tak:
    Code:

    __main_stack_size = 1024;
    __process_stack_size = 1024;

    MEMORY
    {
       rom (rx)   : org = 0x08000000, len = 512k
       ram (rwx)   : org = 0x20000000, len = 64k
    }


    Ale nie chcę ubić procka. Nie znalazłem opisu modyfikacji tego skrytpu. Same chińskie strony :)
  • Helpful post
    #48
    Freddie Chopin
    MCUs specialist
    Nie ma tu żadnej filozofii - zmieniasz sobie te cztery linijki według uznania/potrzeb i już (;

    4\/3!!
  • #49
    qscgu
    Level 34  
    Dobra dzięki, wszystko jest jak trzeba. Teraz się będę zmagał z USB ale to już inny wątek.