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

[Rozwiązano] [ATMEGA] WinAvr - ilość RAMu

mgradzki 16 Sty 2009 14:12 2762 17
  • #1 6007160
    mgradzki
    Poziom 16  
    Witam
    Pytanie będzie lamerskie, ale trudno.
    Napisałem sobie program w C (WinAvr) i chciałbym jakoś przesymulować, czy wystarczy RAMu . W programie zadeklarowałem kilka sporych tablic i nie wiem, czy RAMu wystarczy na stos, czy program mi się gdzieś nie wywali.

    To juz drugie podejście, w pierwszym przez pomyłkę zadeklarowałem zbyt duże tablice, program skompilował się i próbował działać czasami wywalając śmieci na LCD.

    Wolałbym uniknąć takich niespodzianek, więc chciałbym jakoś nauczyć się określać, czy już mi brakuje pamięci, czy jeszcze nie. Na razie to jestem w stanie policzyć sobie ile bajtów mam zadeklarowane w zmiennych globalnych.

    Jeśli ktoś wie, jak to sprawdzić, to będę wdzięczny za info.
  • #2 6007267
    Freddie Chopin
    Specjalista - Mikrokontrolery
    nie da sie wprost okreslic jaki rozmiar stosu bedzie potrzebny. mozna za to napisac sobie swego rodzaju funkcje kontrolujaca, ktora bedzie sprawdzala wartosc SP. najlepiej w postaci przerwania od timera.

    mozna tez recznie, w symulatorze lub debuggerze, podgladac wartosc rejestru SP.

    4\/3!!
  • #3 6044399
    rpal
    Poziom 27  
    CodeVision nawet w tej wersji demo (ograniczenie do 2kB kodu) sprawdza stos i pamięć tak RAM jak i EEPROM. Poza tym można wielkość stosu sobei deklarować. Więc jesli nie wiesz w czym rzecz po próbuj tego kompilatora. Ale niestety on nie jest za darmo w pełnej wersji.
  • #4 8818464
    ginar
    Poziom 21  
    Cytat:
    mozna tez recznie, w symulatorze

    jeśli chodzi o AVRStudio to zajętość Ramu w dowolnym punkcie programu oblicza się
    poprzez sumowanie (.sekcji data + .bss + .noinit) oraz wskaźnika stosu SP(liczonego w kierunku malejących adresów)?Co z obszarem "heap"?
  • #5 8818900
    tmf
    VIP Zasłużony dla elektroda
    Takie liczenie jak piszesz jest tyle warte co wróżenie z fusów. Niestety nie da się prosto policzyć ile program zajmuje RAM - ani nie przewidzisz ile miejsca zajmą zmienne lokalne, ani ile zajmie sterta, ani stos. Znając program można to z grubsza próbować oszacować, ale żeby dobrze trafić to trzeba być niezłym magikiem. Albo jak pisze Freddie - napisać funkcję kontrolującą stos, odpalić w symulatorze i zobaczyć jak wygląda pamięć, albo wykorzystać JTAGa i ustawić pułapki na dostęp do pamięci. A najprościej - jak podejrzewasz, że może ci nie starczyć pamięci to weź większy procesor - w końcu zapewne nie robisz milionowych serii, gdzie oszczędność kilku złotych przekłada się na spore pieniądze.
  • #6 8819009
    ginar
    Poziom 21  
    Teoretycznie funkcja malloc() przy braku miejsca zwraca NULL- jednak nie używam dynamicznej alokacji pamięci także ten sposób odpada
    Cytat:
    napisać funkcję kontrolującą stos, odpalić w symulatorze

    tylko jak taka funkcja miała by wyglądać coby informowała o nałożeniu się stosu na sekcje danych...
    jedyne rozwiązanie jakie mi przychodzi do głowy to właśnie porównywać (jak pisał Freddi - w przerwaniu) wsk. SP ze wsk. ustawionym na pozycji (.sekcji data + .bss + .noinit)- jeśli SP jest poniżej tej wartości to jest ok.
  • #7 8819043
    michalko12
    Specjalista - Mikrokontrolery
    Wypełnij obszar stosu znaną wartością i za pomocą tej funkcji sprawdzaj jak głęboko stos został naruszony

    Dodano po 2 [minuty]:

    Możesz tez sprawdzać tylko kilka ostatnich np 16 czy nie zostało naruszonych i w razie czego wywołać tryb ala "Panic"
  • #8 8819063
    tmf
    VIP Zasłużony dla elektroda
    Raczej jeśli jest powyżej. W tym celu nie trzeba korzystać z przerwań - wystarczy na końcu segmentu danych umieścić zmienną i nadać jej charakterystyczną wartość. Potem można sobie ją sprawdzić, np. przy pomocy JTAG - jeśli zmieniła wartość to coś ją nadpisało - praktycznie może to być tylko stos. W przypadku sterty już tak pięknie nie jest - ale tu z pomocą przychodzą memory breakpoints na JTAG. Albo... pracowicie w przerwaniach sprawdzać SP.
    malloc przy braku miejsca oczywiście zwróci null, ale to przy braku miejsca na stercie, a nie przy konflikcie z SP. Z drugiej strony, zwróci null i co dalej? Co program ma z tą informacją zrobić? Taka sytuacja w systemie embedded bez OS nie ma prawa wystąpić.
  • #9 8819072
    mirekk36
    Poziom 42  
    Żeby nie było - można w bardzo prosty, wręcz rewelacyjny sposób ;) może nie przewidzieć ile zajmie stos - ale przewidywania nie są trudne jak pisali już niektórzy w tym temacie.

    - nie trzeba też zaraz kupować jakichś płatnych kompilatorów ;) używać debugerów skomplikowanych programatorów itp

    .... za to wystarczy taki najzwyklejszy w świecie "monitor stosu" czyli stack monitor, który pozwala oszacować czy w trakcie działania programu dochodzi nam do kłopotów ze stosem w tym sensie, że zaczyna on albo niebezpiecznie się rozrastać i zbliżać do obszaru przetrzymywanych zmiennych globalnych - i odpowiednio zareagować ;)

    Program jest prosty jak DRUT, nie potrzebuje żadnych zasobów mikrokontrolera w sensie np Timerów itp

    Za to Z KAŻDEGO !!! miejsca programu można sobie sprawdzić ile wolnych i jeszcze nie używanych komórek pamięci RAM pozostało - nie naruszonych ani przez stos ani przez zmienne globalne.

    Oczywiście główna zaleta tego monitora polega na tym, że gdy dzieje się coś dziwnego i zaraz podejrzewamy STOS - to można sprawdzić czy to rzeczywiście on ;) jest podejrzanym "w sprawie". Często okaże się, że to nie stos.

    Nie będę tu opisywał jak to działa i jak to odpalić czy korzystać, wszystko jest w komentarzach i powinno być zrozumiałe dla każdego - ale jak coś to pytajcie. Ja tego nieraz używam i przyznam, że fajnie działa.
  • #10 8839396
    ginar
    Poziom 21  
    W moim przypadku stos nakładał się na zmienne globalne, ale przeglądałem niemal, że ręcznie w symulatorze jego położenie..
    @mirekk36
    1.testowałeś ten programik na innych procesorach niż są wymienione w nagłówku tj.ATmega88/168?
    2.w jaki sposób umieścić
    extern uint8_t __stack;
    Cytat:
    ..at the bootom of the stack.
  • #11 8839875
    mirekk36
    Poziom 42  
    ginar napisał:
    1.testowałeś ten programik na innych procesorach niż są wymienione w nagłówku tj.ATmega88/168?


    Ja go nie testowałem ;) ja go czasami / często używam i to na dowolnym procku AVR, podkreślam - DOWOLNYM. Przeanalizuj sobie tych kilka linijek programu bo nie jest ich za wiele ;) ...

    ginar napisał:
    2.w jaki sposób umieścić
    extern uint8_t __stack;
    Cytat:
    ..at the bootom of the stack.


    Ale co ty chcesz umieszczać w ogóle ? ;)


    to symbol zdefiniowany na poziomie linkera i dlatego masz extern w deklaracji. Nic nie musisz robić żeby korzystać na dowolnym procku z tego monitora poza normalnym dołączeniem za pomocą #include ;)

    a potem do twojej dyspozycji jest prosta funkcja: StackCount()
  • #12 8840047
    ginar
    Poziom 21  
    właśnie chodziło mi o extern ale widzę, że extern uint8_t __stack _end nie są przypadkowymi nazwami, więc nie ma problemu:)
  • #13 8840066
    mirekk36
    Poziom 42  
    ginar napisał:
    właśnie chodziło mi o extern ale widzę, że extern uint8_t __stack _end nie są przypadkowymi nazwami, więc nie ma problemu:)


    dokładnie

    _end to miejsce gdzie kończą się zmienne globalne w pamięci ;)
  • #14 20287281
    Karol966
    Poziom 31  
    mirekk36 napisał:
    Za to Z KAŻDEGO !!! miejsca programu można sobie sprawdzić ile wolnych i jeszcze nie używanych komórek pamięci RAM pozostało - nie naruszonych ani przez stos ani przez zmienne globalne.


    Jeżeli w programie występuje nadpisywanie RAMu to można w dowolnym jego miejscu sprawdzać SP? Kiedy SP może się przepełnić, np w czasie przerwań albo wywoływania funkcji zwłaszcza gdy operuje się na większych buforach/ stringach?
  • #15 20288019
    tmf
    VIP Zasłużony dla elektroda
    Karol966 napisał:
    Jeżeli w programie występuje nadpisywanie RAMu to można w dowolnym jego miejscu sprawdzać SP? Kiedy SP może się przepełnić, np w czasie przerwań albo wywoływania funkcji zwłaszcza gdy operuje się na większych buforach/ stringach?

    SP możesz odczytać w dowolnym miejscu, to przecież jeden z dostępnych rejestrów MCU, ale... średnio to pomaga. Owszem, zauważysz, że SP niebezpiecznie się zbliża do zmiennych, co może sugerować potencjalny problem, ale to mało. Nie wiesz, czy w programie nie wystąpi jakaś sekwencja zdarzeń, która krótkotrwale przepełni stos - do tego najprościej użyć sprzętowego debugera i pułapek na adresy, alternatywnie wypełnić wolną pamięć wzorcem i patrzeć dokąd maksymalnie sięgał stos.
    Stos może przepełnić rekurencyjne wywołanie funkcji, zagnieżdżone przerwania, wielokrotnie zagnieżdżone funkcji, funkcje mające duże zmienne lokalne itd.
  • #16 20478533
    Karol966
    Poziom 31  
    Mam program który zachowuje się dziwnie. Testowany na wielu urządzeniach (kilkadziesiąt sztuk) i na jednym potrafi działać tygodniami a na innych po kilku dniach potrafi się wysypać. Może trafiłem na podrobione procesory (połowa była kupiona w chinach a druga połowa w PL), osiwieć idzie.
    Używałem w/w funkcji stackmon i za każdym razem widzę wartość 0, to możliwe?
  • #17 20945184
    fizyk_xyz
    Poziom 11  
    @ElektrodaBot A jak sprawdzać wolną pamięć w czasie pracy programu na AVR, podaj przyklad kodu

    Dodano po 1 [minuty]:

    @ElektrodaBot A uwzględniając stos i stertę?
  • #18 20945197
    ElektrodaBot
    AI od OpenAI ChatGPT4
    fizyk_xyz napisał:
    A jak sprawdzać wolną pamięć w czasie pracy programu na AVR, podaj przyklad kodu

    Dodano po 1 [minuty]:
    Cześć! Bardzo dobrze, że pytasz o monitorowanie wolnej pamięci w trakcie pracy programu na mikrokontrolerach AVR, ponieważ jest to ważny aspekt w projektowaniu stabilnych i efektywnych aplikacji. Istnieje kilka metod na sprawdzanie dostępnej pamięci RAM, ale jedną z prostszych i częściej stosowanych jest technika oparta na sprawdzaniu stosu i sterty (heap).

    Zasada działania tej metody polega na umieszczeniu zmiennej w pamięci w taki sposób, aby była ona jak najbliższa końca sterty (lub na jej początku, w zależności od kierunku wzrostu sterty). W miarę wykonywania programu i alokowania pamięci na stercie, a także zwiększania się rozmiaru stosu (poprzez wywoływania funkcji), wolne miejsce między stosem a stertą będzie się zmniejszać. Poprzez regularne sprawdzanie odległości między stertą a stosu, możemy uzyskać informację o dostępnej pamięci RAM.

    Oto przykład prostego kodu w C, który demonstruje, jak można realizować taką funkcję w AVR:

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


    Warto zwrócić uwagę, że w zależności od konkretnego środowiska programistycznego i konfiguracji projektu, może być konieczne dostosowanie powyższego kodu (np. deklaracje zewnętrznych zmiennych mogą się różnić). Należy również pamiętać, że ta metoda nie jest doskonała i może nie uwzględniać wszystkich skomplikowanych przypadków alokacji pamięci, zwłaszcza gdy używamy zaawansowanych funkcji bibliotek lub systemów operacyjnych czasu rzeczywistego. Niemniej jednak, jest to użyteczne narzędzie do monitorowania użycia pamięci w prostszych aplikacjach.

    Mam nadzieję, że ta odpowiedź jest pomocna! Jeśli masz więcej pytań lub potrzebujesz dodatkowego wyjaśnienia, śmiało pytaj. Powodzenia z Twoim projektem na AVR!
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
REKLAMA