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

[STM32L4] [GCC, FreeRTOS] Hardfault podczas korzystania z sprintf z floatami.

conkerkh 22 Kwi 2017 19:30 1908 14
REKLAMA
  • #1 16429393
    conkerkh
    Poziom 7  
    Posty: 15
    Witam, postaram sie opisac problem najprosciej jak to mozliwe. Mianowicie zauwazylem ze przy kompilacji z parametrami:
    -spec=nano.specs -u _printf_float -specs=rdimon.specs -lc -lrdimon

    kazde odwolanie w zadaniu do sprintf w ktorym znajduje sie float powoduje hardfault. Kiedy korzystam z biblioteki nosys bez opcji semihostingu ten problem nie wystepuje. Wiem ze sprintf moze sie odwolywac do malloc() oraz free(), z tego co sie dowiedzialem to wlasnie w regionach gdzie zwalniany jest zalokowany bufor wystepuje hardfault. Kiedy korzystam z sprintf z floatem przed odpaleniem kernela wszystko jest ok. Dodam tylko ze zadania maja wystarczajaco duzo zalokowanej pamieci, wiec to napewno nie jest problem. Gdzie szukać dalej, co zmienić bede wdzięczny za sugestie.
  • REKLAMA
  • #2 16429412
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #3 16429424
    conkerkh
    Poziom 7  
    Posty: 15
    Piotrus_999 napisał:
    w port.c

    zmien pxTopOfStack -= 2; na pxTopOfStack -= 1;

    kiedyś miałem podobny problem.

    Ale to też zależy od wersji RTOS-a.

    Generalnie jest z tym trochę problemów.


    U mnie to tak wyglada:

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


    czyzby linia z -= 5 byla odpowiednim miejscem do grzebania? Reszta wyglada jakby byla wyrownana.
  • #4 16429508
    Konto nie istnieje
    Konto nie istnieje  
  • #5 16429543
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Jeśli używasz stosunkowo "starego" newliba (starszy niż max kilka miesięcy, mogę dokładnie sprawdzić), to malloc() w wersji "nano" _NIE_ nadaje się do działania wielowątkowego choćbyś nie wiem co zrobił. W nowszych newlibach trzeba sobie przedefiniować dwie funkcje i dodać tam np. blokowanie mutexów. Inna opcja to przedefiniowanie malloc() i free() na funkcje z FreeRTOSa (jeśli nie używa on malloc() / free() z newliba [; ).
  • #6 16430012
    conkerkh
    Poziom 7  
    Posty: 15
    Freddie Chopin napisał:
    Jeśli używasz stosunkowo "starego" newliba (starszy niż max kilka miesięcy, mogę dokładnie sprawdzić), to malloc() w wersji "nano" _NIE_ nadaje się do działania wielowątkowego choćbyś nie wiem co zrobił. W nowszych newlibach trzeba sobie przedefiniować dwie funkcje i dodać tam np. blokowanie mutexów. Inna opcja to przedefiniowanie malloc() i free() na funkcje z FreeRTOSa (jeśli nie używa on malloc() / free() z newliba [; ).


    Faktycznie korzystanie z newliba bez nano poprawia sytuacje i sie nie wykrzacza. Natomiast pojawia sie dosc dziwny problem ze float'y nie sa poprawnie wyswietlane jesli uprzednio nie skorzystalem z semihostingu (nie wywolalem printf()). Nie wiem jaki ma to sens zupelnie. Zdefiniowalem malloc i free tak zeby korzystaly z pvPortMalloc i vPortFree. Generalnie mam to tak ustawione ze sprawdzam rejestr DHCSR czy jest ustawiony bit debugowania i nie wywoluje nic odpowiedzialnego za semihosting jesli debuger nie jest wpiety ale z tego co widze to nie wystarcza i chyba musze sobie po prostu zrobic druga konfiguracje, ktora bedzie inaczej linkowac biblioteki.
  • REKLAMA
  • #7 16430041
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Jeśli źle Ci się wyświetlają floaty przy użyciu funkcji typu printf(), to na 99% masz źle wyrównany stos. Musi być on wyrównany do 8 bajtów, przy wyrównaniu do 4 jest właśnie (m.in.) taki efekt jak opisujesz.
  • #8 16430056
    Konto nie istnieje
    Konto nie istnieje  
  • #9 16432535
    conkerkh
    Poziom 7  
    Posty: 15
    Mysle ze finalnie wywale po prostu semihosting... Bede korzystac z VCP i logow do karty pamieci bo nie mam sily juz z tym walczyc. Stos niby jest wyrownany bo jest to sprawdzane przez assert() i przechodzi przez to... Dzieki panowie za rady, jesli ktos ma jeszcze jakies pomysly chetnie wyslucham moze ewentualnie uda sie cos z tym zrobic, jak nie to trudno.
  • #10 16432542
    Konto nie istnieje
    Konto nie istnieje  
  • #11 16432690
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Ja bym się tam nie poddawał. Jeśli nie działa Ci printf() z floatami, to - jak pisałem - jest spora szansa, że w projekcie masz poważny problem związany z wyrównaniem stosów. Zignorujesz semihosting to w końcu trafisz na inny objaw tego samego, nierozwiązanego problemu. W każdym razie problem z wyrównaniem stosów objawia się też tak, że czasem takie funkcje powinny działać. Jeśli nie działa Ci absolutnie każda i w każdym przypadku, nigdy nie zdarzyło się aby zadziałała poprawnie, to być może jednak problem jest inny. Tak czy siak po prostu ignorując go w jednym miejscu masz szansę trafić na niego w innym miejscu i w innym czasie.

    Stosy wątków może i są wyrównane, ale co ze stosami przerwań oraz co ze stosem głównym (być może to jeden i ten sam stos)? Jaka to wersja RTOSa? Jak jakaś stara, to jednak zacząłbym od aktualizacji. Jaki toolchain, jaka wersja?
  • #12 16434316
    conkerkh
    Poziom 7  
    Posty: 15
    Freddie Chopin napisał:
    Ja bym się tam nie poddawał. Jeśli nie działa Ci printf() z floatami, to - jak pisałem - jest spora szansa, że w projekcie masz poważny problem związany z wyrównaniem stosów. Zignorujesz semihosting to w końcu trafisz na inny objaw tego samego, nierozwiązanego problemu. W każdym razie problem z wyrównaniem stosów objawia się też tak, że czasem takie funkcje powinny działać. Jeśli nie działa Ci absolutnie każda i w każdym przypadku, nigdy nie zdarzyło się aby zadziałała poprawnie, to być może jednak problem jest inny. Tak czy siak po prostu ignorując go w jednym miejscu masz szansę trafić na niego w innym miejscu i w innym czasie.

    Stosy wątków może i są wyrównane, ale co ze stosami przerwań oraz co ze stosem głównym (być może to jeden i ten sam stos)? Jaka to wersja RTOSa? Jak jakaś stara, to jednak zacząłbym od aktualizacji. Jaki toolchain, jaka wersja?


    Genralnie wyglada to tak. Mam linker w konfiguracji release ustawiony tak:
    -specs=nosys.specs -u _printf_float -specs=rdimon.specs

    to dziala bez zadnego problemu sprintf z floatem chodzi. Nosys i tak wiadomo jest ignorowany tutaj.

    Druga konfiguracja debug wyglada tak:
    -specs=rdimon.specs -u _printf_float -lc -lrdimon


    Z tego co wiem musze to tak linkowac bo semihosting nie bedzie dzialac. Podejrzewam ze to jest wlasnie wina tego wszystkiego. Sprintf przy tej drugiej konfiguracji nie dziala poprawnie do momentu wywolania chociaz raz printf, bo wypisuje bzdury ale sie nic nie wykrzacza, jak wywolam juz printf to sprintf zaczyna dzialac z floatami jak powinien. To jest normalny objaw?

    Toolchain najnowszy ze strony arma. RTOS jest w wersji 9.0.0
  • REKLAMA
  • #13 16434373
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    conkerkh napisał:
    To jest normalny objaw?

    Nigdy nie używałem semihostingu, ale przypuszczam że zachowanie które obserwujesz nie jest normalne [;
  • #14 16434518
    conkerkh
    Poziom 7  
    Posty: 15
    Freddie Chopin napisał:
    conkerkh napisał:
    To jest normalny objaw?

    Nigdy nie używałem semihostingu, ale przypuszczam że zachowanie które obserwujesz nie jest normalne [;


    Chyba musze dokladnie przestudiowac te opcje linkowania bibliotek i toolchain bo chyba cos sie tam dzieje czego nie widze i jest poza moja kontrola.
  • #15 16434810
    rajszym
    Poziom 21  
    Posty: 272
    Pomógł: 48
    Ocena: 18
    Tak dla porządku: wywołujesz funkcję "initialise_monitor_handles"?

Podsumowanie tematu

✨ Użytkownik zgłasza problem z występowaniem hardfaultów podczas korzystania z funkcji sprintf z typem float w środowisku FreeRTOS na mikrokontrolerze STM32L4. Problem pojawia się przy użyciu specyfikacji kompilacji, które włączają semihosting i malloc, co prowadzi do błędów związanych z alokacją pamięci. Użytkownicy sugerują sprawdzenie wyrównania stosu, wersji newlib oraz konfiguracji linkera. Wskazano, że printf() z floatami może nie działać poprawnie bez wcześniejszego wywołania printf(), co może wskazywać na problemy z inicjalizacją. Użytkownik rozważa rezygnację z semihostingu na rzecz logowania przez VCP oraz modyfikację alokacji pamięci, aby używać funkcji FreeRTOS.
Wygenerowane przez model językowy.
REKLAMA