Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32] Stos zrzuca rejestry do zmiennych globalnych

Mess-gd 05 Paź 2009 11:10 2669 9
  • #1 05 Paź 2009 11:10
    Mess-gd
    Poziom 14  

    Witam,

    Mam problem z programem. Otóż, po wejściu do funkcji rejestry zrzucane są w nieodpowiednie miejsce. W moim przypadku jest to bufor LCD, co powoduje wyświetlenie kompletnych bzdur na moim wyświetlaczu.

    Przed wejściem do funkcji:
    [STM32] Stos zrzuca rejestry do zmiennych globalnych

    Po wejściu do funkcji:
    [STM32] Stos zrzuca rejestry do zmiennych globalnych

    Nie wiem czy to problem skryptu linkera, czy może startupa. Jakieś pomysły?

    Pozdrawiam,
    P. M.

  • #2 05 Paź 2009 11:20
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Chyba coś te obrazki nie działają. Zamiast obrazków wrzuć lepiej kod i napisz dokładnie co się dzieje i gdzie. Zapewne masz zbyt mały stos.

    4\/3!!

  • #3 05 Paź 2009 11:21
    94075
    Usunięty  
  • #4 05 Paź 2009 11:32
    Mess-gd
    Poziom 14  

    Obrazki zmieniłem. Winą jest linker. Dodam na końcu 2 linkery których używam, dobry i zły. Dobry jest starym linkerem, który nie ma HEAP'a (Freedie chyba wiesz o co chodzi) drugi jest z HEAP'em z przykłady migających LEDów ze strony Freddiego.

    Chodzi o to, że po wywołani funkcji np. f_open (FatFS) na początku tej funkcji w assemblerze jest instrukcja

    Code:
    push (r4, r5, r6, r7, rl)

    Wrzuca mi ona wartości w rejestrach na stos. Najprawdopodobniej stos jest ustawiony w środku bufora od LCD, a co za tym idzie na LCD wyświetlają mi się bzdury.

  • #5 05 Paź 2009 12:02
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Obrazki są nie zmienione.

    Z samych skryptów linkera niewiele wynika, bo ten mój był mocno przezemnie testowany, zarówno w C jak i w C++, z alokacją dynamiczną, z dziwnymi stosami itp. Wrzuć cały projekt, to się wtedy okaże, bo na razie niewiele wynika z informacji które zamieściłeś.

    4\/3!!

  • #6 05 Paź 2009 12:29
    Mess-gd
    Poziom 14  

    Nie wiem czemu wg was te linki nie działają :) Daje bezpośredni adres:

    http://img36.imageshack.us/img36/6918/step1fr.jpg

    http://img27.imageshack.us/img27/196/beznazwyai.jpg

    Dorzucam projekt. Mam nadzieje ze się odnajdziesz. Myślę, że za wszystko odpowiada skrypt linkera + startup.

    Na chwile obecna ustawione jest: lib/etc/ld/stm32f103vb.ld (zly) i lib/stm32/CMSIS/Core/CM3/startup/arm/startup_stm32f10x_hd.c

  • #7 05 Paź 2009 12:47
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Mówiłem o zbyt małym stosie i wciąż to podtrzymuję. W tym skrypcie, który jest wg Ciebie "dobry", stos jest skonfigurowany na cały wolny ram, w skrypcie który oceniasz jako "zły" - zaledwie 1kB. Łatwo sprawdzić, czy stos nie najeżdża na dane, bo wystarczy w tym krytycznym momencie zobaczyć jaka jest wartość rejestru r13 (sp) i porównać go z adresami sekcji z pliku .map. Albo zwieksz sobie stos na 10kB to zobaczysz, że będzie działać.

    Tak w ogóle to w startupie wykorzystujesz stałą __idata_start, której nigdzie w tych skryptach linkera nie widzę.

    4\/3!!

  • #8 05 Paź 2009 13:00
    94075
    Usunięty  
  • #9 05 Paź 2009 17:51
    Mess-gd
    Poziom 14  

    Freddie Chopin napisał:

    Tak w ogóle to w startupie wykorzystujesz stałą __idata_start, której nigdzie w tych skryptach linkera nie widzę.


    Skrypt likera linia 127:
    Code:
    __idata_start = __text_end;


    Dodano po 5 [minuty]:

    Zgadza się. Zwiększenie stosu powoduje, że błąd nie występuje. Jednak jak uchronić się od tego w przyszłości? W tym przypadku wyświetlały się bzdury na LCD ale w innym może nieźle namieszać w innych zmiennych, w których wykrycie błędu nie będzie takie proste.

  • Pomocny post
    #10 05 Paź 2009 19:43
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Pierwsza opcja to oczywiście zdefiniowanie NAPRAWDĘ DUŻEGO stosu, ale to średnie rozwiązanie jak wiadomo [; Do rozbudowanej aplikacji na ARMa myślę że należy liczyć minimum 1kB, jeśli używa się jakichś potwornych funkcji standardowych (printf!) i to głęboko to lepiej zaopatrzyć się w 2kB (o apetycie tych funkcji na pamięć pisałem ostatnio https://www.elektroda.pl/rtvforum/topic1384751.html )

    Metod analizy stosu jest wiele [;

    HARDWARE'OWA:
    Można próbować "sprzętowo". Umieszczając stos na początku pamięci jego "przepełnienie" spowodować powinno jakiś wyjątek rdzenia (dostęp do nieistniejącej pamięci). Niestety sprawa komplikuje się, gdy stosów jest wiele (każdy ARM <: )

    SOFTWARE'OWA:
    Można w startupie wypełnić cały obszar przeznaczony na stos jakąś znaną wartością (szczególnie polecane są złożenia dwóch 4 literowych "wyrazów HEX", takie jak 0xDEADBEEF, 0xBABEFACE, 0xDEADBABE itp [; ). Operację tą należy wykonać dla stosu "zbyt dużego" - teraz można po pewnym czasie działania programu sprawdzić, jaka część stosu "leży odłogiem", a jaka została wykorzystana, dzięki czemu można dopasować jego rozmiar do rzeczywistych potrzeb. Analizę taką można zrobić ręcznie, albo napisać kawałek kodu, który pracowałby w tle (niech będzie uruchamiany z jakiegoś przerwania co jakiś czas np) i sprawdzał aktualne zużycie, zapamiętywał wartość największą itp. Aplikacja taka mogłaby nawet ostrzegać, jeśli zużycie stosu sięgnie - na przykład - 95%.

    Sprawa jest ciężka, a wiele stosów tylko ją komplikuje [; Swoją drogą - zaczynam wątpić w zalety wielu stosów [; Albo inaczej - obecnie nie widzę żadnych zalet z posiadania wielu stosów, zwłaszcza w językach wysokiego poziomu. Ktoś może mnie oświecić?

    BTW - Założenie, że inicjalizatory sekcji .data zaczynają się tam, gdzie kończy się .text to przykład proszenia się o kłopoty [; Zobacz jak to jest zrobione w moich najnowszych skryptach linkera.

    4\/3!!

TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo