danielll Napisano Maj 10, 2021 Udostępnij Napisano Maj 10, 2021 Cześć. Czy możecie mi polecić jakieś sposoby na szukanie przyczyn HardFaulta w programie? Do tej pory zazwyczaj udawało mi się znaleźć nieprawidłowe fragmenty przy pomocy debuggera, lecz tym razem nie mogę się niczego dopatrzeć. Najprawdopodobniej mam gdzieś błąd z dostępem do pamięci lub jakiś wyciek. Debugger przerywa mi na funkcji odczytu z karty SD w bibliotece FatFS ale nie będę się rozpisywał na ten temat bo to zbyt rozległy program. Macie może jakieś sposoby czemu można się przygłądać, jak znaleźć jakieś wskazówki, co sprawdzić? Odpalanie kodu po fragmentach niezbyt wchodzi w grę bo próbuję uruchomić na STMie kod który wcześniej uruchomiłem na windowsie i składa się z 12 klas C++ i wycinanie fragmentów byłoby mocno uciążliwe. Link do komentarza Share on other sites More sharing options...
Luuke Maj 10, 2021 Udostępnij Maj 10, 2021 Cześć, Masz uruchomione pozostałe przerwania rdzenia (UsageFault, BusFault itd)? HardFault może być spowodowany też brakiem obsługi właśnie tych przerwań. Cytat z Programming Manual PM0214 dla STM32F411CE (Cortex M4) Cytat A hard fault is an exception that occurs because of an error during exception processing, or because an exception cannot be managed by any other exception mechanism. Hard faults have a fixed priority of -1, meaning they have higher priority than any exception with configurable priority. 2 Link do komentarza Share on other sites More sharing options...
danielll Maj 10, 2021 Autor tematu Udostępnij Maj 10, 2021 Rdzeń programu jest wygenerowany w CubeMX i wszystko chodziło w poprzedniej wersji kodu. Dlatego właśnie obstawiam że problem jest z dostępem do pamięci w nowo napisanym kodzie. Coś dzisiaj znalazłem na necie że można odczytać rejestry przerwań UsageFaut, BusFault i z nich spróbować się czegoś dowiedzieć Link do komentarza Share on other sites More sharing options...
Luuke Maj 10, 2021 Udostępnij Maj 10, 2021 Jeśli będziesz mieć włączoną obsługę tych przerwań to nie będziesz musiał ręcznie sprawdzać tych błędów. Przerwanie samo się wywoła i to Cię już nakieruje gdzie szukać problemu. A jeśli żadne z tych przerwań się nie wywoła pomimo, że będą włączone to będzie znaczyło, że problem leży gdzieś indziej. 1 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
danielll Maj 10, 2021 Autor tematu Udostępnij Maj 10, 2021 Nie wiem do końca na jakiej zasadzie jest to napisane w HALu, ale program zatrzymuje mi się na pętli HardFaulta. Nie wiem czy jest sposób wyciągnąć z tego więcej informacji bez odczytania tych rejestrów. Chyba, że jest możliwość uruchomienia jeszcze jakichś innych przerwań bo o ile wiem to hardFault jest jednym z głównych w którym zawiera się kilka innych grup. Link do komentarza Share on other sites More sharing options...
Luuke Maj 10, 2021 Udostępnij Maj 10, 2021 Tu nie chodzi o to jak jest HAL napisany tylko jak działają ARMy. Jeśli się zatrzymuje w HF to przyczyną może być m.in. brak obsługi BF, UF, MMF. W takim przypadku bardziej nawet może się przydać biblioteka CMSIS niż HAL. Zacznij od włączenia i napisania obsługi przerwań błędów w rdzeniu i wtedy sprawdź w którym przerwaniu ląduje procek. Na tej podstawie odfiltrujesz sporą część możliwych przyczyn HardFaulta. Do tego pobierz Programming Manual dla Twojego procka i poczytaj o rdzeniu i jego błędach. W załączniku przykładowe typy błędów w Cortex-M4. 1 Link do komentarza Share on other sites More sharing options...
Popularny post kaworu Maj 11, 2021 Popularny post Udostępnij Maj 11, 2021 Dnia 10.05.2021 o 14:57, Luuke napisał: Zacznij od włączenia i napisania obsługi przerwań błędów w rdzeniu i wtedy sprawdź w którym przerwaniu ląduje procek. Mi się ta jednak wydaje, ze prościej po prostu jak już wejdzie w HF rzucić okiem na cały jeden rejestr (CFSR), którego zawartość poda przyczynę wylądowania w HF. No ale możesz napisać obsługę kilku dodatkowych przerwań a potem jak już w któreś wpadnie (lub nie bo znów wskoczy do HF) rzucić okiem na ten sam rejestr (bo są tam zawarte MMFSR, UFSR i BFSR) aby poznać dokładny powód. 3 Link do komentarza Share on other sites More sharing options...
Luuke Maj 12, 2021 Udostępnij Maj 12, 2021 Jak najbardziej! Nie ma koniecznie potrzeby uruchamiać tych przerwań i można z samego HF to sprawdzić. 2 Link do komentarza Share on other sites More sharing options...
danielll Maj 19, 2021 Autor tematu Udostępnij Maj 19, 2021 Dzięki. Aktywowałem sobie wszystkie przerwania, odcytalem rejestry i pamięć z ostatnich elementów stosu. Po tym jak to zrobiłem znalazłem w CubeIDE narzędzie które pokazuje to wszystko bez żadnego kodu 😄 Przy hardFaulcie w rejestrze wysoki jest bit IBUSERR. Powyżej informacja z manuala na ten temat, z której niewiele jestem w stanie wywnioskować. W necie znalazlem informacje że przyczyną może być uszkodzony stos co powoduje odwoływanie się do zajętej pamięci. Próbowałem zwiększyć wartość stosu w CubeMX lecz bez skutku. Może ktoś jest w stanie mi podpowiedzieć jakim elementom mógłbym się przyjrzeć? BusFault jest chyba najgorszym błędem do debugowania, ponieważ nie wywala go w miejscu wystąpienia wadliwego fragmentu kodu. https://github.com/danielbr33/OLED_complete/tree/master Jakby ktoś chciał spojrzeć co to wogóle za program to wyżej wrzuciłem link do gita. Jest to obsługa wyświetlacza i interfejsu, dość rozbudowanego ze względu na czytanie z jsona i karty SD. HardFaulta wyrzuca na inicjalizacji karty SD, lecz po wyrzuceniu jej obsługi pojawia się w innym miejscu. Jak uruchamiam sam interfejs bez wyświetlacza to wszystko działa, wyświetlacz bez interfejsu też. Może program jest napisany zbyt wysokopoziomowo jak na mikrokontroler i faktycznie przepełnia się stos? Korzystam z STM32F429ZI więc jest to całkiem dobry proc. 1 Link do komentarza Share on other sites More sharing options...
Luuke Maj 20, 2021 Udostępnij Maj 20, 2021 (edytowany) Spojrzałem do repozytorium: oled2 = new SSD1306(i2c_settings); Jeśli nie ma takiej konieczności staraj się nie używać dynamicznej alokacji pamięci, szczególnie w systemach wbudowanych. Nie bez powodu standard MISRA zabrania użycia jakiejkolwiek dynamicznej alokacji pamięci. Sterta (heap) może się nadmiernie rozrosnąć i nadpisać obszar stosu (stack), a wtedy to już czarna magia zaczyna się dziać 🙂 W związku z powyższym na początek proponuję zamienić powyższą linijkę na coś takiego: SSD1306 oled2 { i2c_settings }; edit: Nie bawiłem się FreeRTOSem, ale pamiętam, że jest wybór statyczna/dynamiczna alokacja w jego konfiguracji. Upewnij się, że jest ustawiona statyczna. Edytowano Maj 20, 2021 przez Luuke 1 Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »