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

AtMega8 - program o rozmiarze bliskim 8kB przestaje działać

MirekCz 19 Lip 2007 20:25 1716 13
REKLAMA
  • #1 4096346
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Witam serdecznie,

    Mam mały problemik. Piszę program na AtMega8 i gdy jego rozmiar zbliża się do 8kB to program przestaje działać.
    Wg. testów wynika, że następuje to ok. 7350bajtu programu - większy program nie działa, mniejszy działa bez problemu (jedyne co zmieniam to wielkość bufora danych we flashu).

    Pytanie, co może to powodować?
    Pamięć rezerwowana we flashu?

    (fuse bity dotyczące bootloadera mam nie przestawiane)

    Dziękuje za pomoc
  • REKLAMA
  • #2 4096376
    markosik20
    Poziom 33  
    Posty: 2261
    Pomógł: 208
    Ocena: 147
    Miałem kiedyś podobny problem i sprawa była związana z ustawieniami kompilatora (C dla 51) , oraz musiałem jeszcze raz przeanalizować dokładnie newralgiczne punkty programy (np: wykorzystanie stosu).
    W jakim języku masz napisany program?
    Rozumiem ze program "idzie w maliny" w jakimś konkretnym miejscu?
    Jeżeli tak warto to przeanalizować na symulatorze.
  • #3 4096503
    johny_w
    Poziom 24  
    Posty: 673
    Pomógł: 80
    Ocena: 63
    A jesteś pewien, że ten bufor na 100% jest we flash'u? Pisząc bufor - sugerujesz że jest to tablica zmiennych, która na bierząco pośredniczy w wymianie danych. Jeżeli tak - bufor ten musi znajdować się w ramie. W przypadku AVR nie ma możliwości zapisywania do flasha z pozoimu programu (można to tylko zrobić z sekcji bootloadera).

    A co mówi kompilator na zajętość pamięci? Twój przypadek rzeczywiście bardziej wskazuje na zamazanie stosu niż przepełnienie flasha.

    pzd., JnS
  • #4 4096592
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Ten bufor ma 1024*2 bajty w pełnym rozmiarze.. daleko przekracza to rozmiar pamięci AtMegi.

    Jeżeli bufor zostawie 1024*2 a wywale inny kawałek kodu, to program działa ok. Jeżeli mam cały kod i bufor zmniejsze do mniejwięcej 1200bajtów to też działa ok.

    PS.Jak w GCC dla AVR można zobaczyć ile/jakiej pamięci jest zajęte na program/dane globalne itp?
  • REKLAMA
  • #5 4096651
    johny_w
    Poziom 24  
    Posty: 673
    Pomógł: 80
    Ocena: 63
    Ja korzystam z AVR Studio. Oczywiście piszę w C. Podczas kompilacji dostaję "raport" ile bajtów flasha, ramu i eepromu zużył program.

    Dodatkowo (w razie problemów) korzystam z wbudowanego symulatora. Można w każdym momencie zatrzymać program, sprawdzić zawartość pamięci, wartości zmiennych i stany wszystkich rejestrów uC.

    Ten symulator sprawuje się nieźle w stosunku do programów, które nie są uzależnione od danych wejściowych (jak np. dane z RS, klawiatura, itp.). W przypadku takich projektów stosuję JTAG. Jest to system pozwalający w każdej prawie chwili "wdarcie się" w pamięć i stan zmiennych rzeczywistego układu. Niestety mega8 nie posiada JTAG'a :(

    Jeżeli Twój kod nie jest tajemnicą - umieść go. Zobaczymy co jeste nie tak (ale już nie dziś :) )
  • #6 4096679
    markosik20
    Poziom 33  
    Posty: 2261
    Pomógł: 208
    Ocena: 147
    No nie nazwałbym buforem obszaru danych w pamięci programu. :wink: Do tego lepiej pasuje tablica (ze stałymi). Jeżeli deklarujesz taką tablice (podajesz jej wymiar) i nic w niej nie umieszczasz to kompilator może na to róźnie reagować (w zalażności od ustawień). Za każdym razem kiedy tablica zostaje zadeklarowana w pamięci programu trzeba w niej umieścić dane (podczas deklarowania tablicy), inna sprawa z pamięcią RAM ale jak mówisz problem dotyczy Flash'a.
  • REKLAMA
  • #7 4097154
    andre65
    Poziom 14  
    Posty: 53
    Pomógł: 5
    Nie wiem, co miałeś na myśli pisząc:
    Cytat:
    (jedyne co zmieniam to wielkość bufora danych we flashu)

    Dla mnie taka sprawa ewidentnie "pachnie" nakładaniem się segmentów zmiennych globalnych ze stosem danych lokalnych oraz stosem powrotów z wywoływanych funkcji.
    Generalnie kompilatory nie radzą sobie z automatycznym wyznaczaniem niezbędnych rozmiarów stosów i trzeba je ustawiać ręcznie w odpowiednich opcjach.
    Jak chcesz wiedzieć, co na co może "nachodzić", sprawdź w listingu zakresy deklaracji stosów oraz jakie zmienne z nimi graniczą. Sprawdź też, w którym kierunku wypełniają się stosy w Twoim kompilatorze i tam szukaj problemów.
    Pozdro
  • #8 4097201
    al555
    Poziom 20  
    Posty: 485
    Pomógł: 32
    Ocena: 8
    Witam,
    to rzeczywiście będzie problem ze stosem.

    ande65: czy można w listingach z WinAVR/GCC sprawdzić jaki zakres zajmuje stos ( i jak bardzo będzie się powiększał) czy pozostaje tylko badanie pamięci RAM na działającym procku ( np. przez wstępne zapisanie zakresu pamięci jaki zajmuje w przybliżeniu stos a potem sprawdzanie które komórki zostały zmienione/zapisane przez odkładanie na stosie)

    Pozdrawiam
  • #9 4097420
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Niby wszystko pięknie, ale dlaczego to działa/nie działa jak zwiększam tablicę zadeklarowaną jako stałą i siedzącą w pamięci flash?
    Stos przecież nie siedzi we flashu...

    Przekompiluje to w AVRStudio to może coś nowego się dowiem...
  • #10 4097466
    ogr
    Poziom 15  
    Posty: 137
    Pomógł: 9
    Ocena: 6
    Sprawdz czy przypadkiem nie masz ustawionego FUSE
    Boot Reset Vector Enabled

    Pozdrawiam.
  • #11 4097989
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Nie mam Boot Reset Vectora ustawionego.. zresztą próbowałem już w obie strony - on/off i nic to nie zmieniło.
  • REKLAMA
  • Pomocny post
    #12 4098356
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    czasem problemem okazuje się niestała stała - tablice stałych można przypuszczać, że będą tylko w pamięci flash - przeważnie okazuje się, że kompilator owszem zapisuje sobie tablicę w pamięci flash, ale z początku programu kopiuje sobie ją do ramu - w ten sposób można się odwoływać do komórek takiej tablicy jak do zwykłej pamięci ram (przestrzeń). Może należało by oznaczyć, że tablica ma być tylko w kodzie programu? - szybkie szukanie:
    https://www.elektroda.pl/rtvforum/topic308467.html
    - trzeba dołączyć: #include <avr/pgmspace.h>
    - do deklaracji tablicy dodaje się atrybut "PROGMEM"
    - odczyt komórek za pomocą "PRG_RDB()".....

    ogólnie trzeba się pokręcić wokół tego, że kompilator umieszcza tablice stałych w pamięci ram.
  • #13 4099249
    MirekCz
    Poziom 35  
    Posty: 2220
    Pomógł: 330
    Ocena: 62
    Kolega BoskiDialer ma rację.
    Program po użyciu pgmspace działa już bez niespodzianek.

    Serdecznie dziękuje za pomoc.
  • #14 4100116
    johny_w
    Poziom 24  
    Posty: 673
    Pomógł: 80
    Ocena: 63
    Jednak Twój "bufor" rzeczywiście siedział w ramie!?

Podsumowanie tematu

✨ Program napisany na mikrokontroler AtMega8 przestaje działać, gdy jego rozmiar zbliża się do około 8 kB, co wiąże się z powiększaniem bufora danych deklarowanego jako tablica stała w pamięci flash. Problem wynikał z nieprawidłowego umiejscowienia bufora – mimo deklaracji w pamięci programu, kompilator GCC dla AVR kopiował tablicę do pamięci RAM, co powodowało przekroczenie dostępnej pamięci RAM i kolizję ze stosem. Rozwiązaniem było użycie atrybutu PROGMEM z biblioteki , który wymusza przechowywanie tablicy wyłącznie w pamięci flash oraz odczyt danych za pomocą makr takich jak pgm_read_byte(). Dodatkowo wskazano, że problem nie był związany z ustawieniami fuse bitów bootloadera ani z wektorem resetu. Zalecane jest monitorowanie zużycia pamięci flash i RAM podczas kompilacji (np. w AVR Studio) oraz analiza stosu i segmentów pamięci, gdyż przekroczenie RAM-u lub nakładanie się segmentów może powodować niestabilność programu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA