Dlaczego ATmega128 przekłamuje?

Piszę program na ATmega128 za pomocą edytora AVRSide i kompilatora WinAVR. Program jest juz trochę rozbudowany i zawiły. Jest obsługa przerwań czasowych co mniej więcej 1ms i używane jest sporo zmiennych globalnych. Program obrabia równolegle dwa sygnały A i B z przetwornika A/C. Jeśli sygnał A lub B spełni pewien warunek badany w przerwaniu, w pętli głównej wchodzi w odpowiadającą swojemu kanałowi jedną z dwóch bliźniaczych procedur (dość zawiłych). Jedna ze zmiennych ustawiana jest w menu (wyświetlacz LCD i klawiatura multipleksowana) i przyjmuje wartości 1 lub 0.

Dziwne zjawisko występuje, kiedy program wejdzie w wykonywanie procedury tylko dla kanału B. W trakcie jej wykonywania powoduje samoistne wyzerowanie wspomnianej wcześniej zmiennej. Zmienna ta nie występuje w ogóle w tej procedurze. W całym programie jej wartość może być zmieniana ręcznie tylko w pewnym menu które trzeba specjalnie wywołać sekwencją działań. Podejrzewałem że może jest za mało pamięci RAM (zajętość 83%) i coś zaczyna głupieć. Testowo wywaliłem pewne tabele zajmujące sporo RAM-u i uzyskałem

52% zajętości. Zjawisko się nie zmieniło. Sprawdziłem użycie tablic i nigdzie nie jest przekroczony ich rozmiar.

Zmienna nie jest używana w przerwaniach, ale dla próby dałem ją jako volatile - bez poprawy. Szukanie dokładnie miejsca w procedurze w którym następuje zmiana wartości tej zmiennej, to żmudna czasochłonna praca. Procedura jest duża i pokiełbaszona z wieloma rozgałęzieniami typu case. Przydałaby się jakaś wskazówka do szukania winnego.

Co może powodować ingerencję w wartość zmiennej przez procedurę, w której ta zmienna nie występuje?

Reply to
Darkac
Loading thread data ...

stos?

Reply to
DJ

Użytkownik "DJ" snipped-for-privacy@poczta.onet.pl> napisał w wiadomości news:hb1uet$fia$ snipped-for-privacy@news.dialog.net.pl...

Tak podejrzewałem, ale redukcja zmiennych z 83% zajętości RAM do 52% nie zmieniła nic w tym względzie. Ile może zajmować taki stos? ATmega128 ma 4 KB RAM-u. Polowa pamięci na stos ? Trochę nieprawdopodobne. Kilka wersji programu wcześniej, nie było tego złego zjawiska, a zajętość RAM-u była ponad 80%. Było sporo drobnych zmian, które nie powinny były znacząco wpływać na rozmiar stosu. Ale śledzenie tych zmian to też partaninka.

Reply to
Darkac

Użytkownik "Darkac" snipped-for-privacy@wp.pl napisał w wiadomości news:hb206d$t7q$ snipped-for-privacy@news.lublin.pl...

Stos moze zajmowac dowolnie duzo :-) No nie, sa procki gdzie jest maly, ale jesli jest rekurencja, zagniezdzone przerwania i inne niespodzianki, to moze rosnac. Ale jakby stos zajezdzal zmienna, to zapewne nie ta jedna.

Dodaj pare zmiennych dookola, zobacz czy tylko ta jedna sie zmienia. Albo dodaj nowa zmienna, zmien program zeby z niej korzystal, ale te zostaw i monitoruj.

J.

Reply to
J.F.

Użytkownik "Darkac" snipped-for-privacy@wp.pl napisał w wiadomości news:hb1sbu$qoq$ snipped-for-privacy@news.lublin.pl...

której ta > zmienna nie występuje?

wyjechanie za tablicę / zapis przez źle ustawiony wskaźnik?

e.

Reply to
entroper

(..)

Czyli nalezy rozumiec, ze jest to zmienna globalna???

"Recznie" to ty musisz ja zmienic, kompilator ja zmienia poprostu tam zapisujac ;) Chyba ze masz na mysli iz aby dokonac zmiany tej zmiennej trzeba wykonac sekwencje polecen, np. jak przy zapisie do pamieci Flash, ale wtedy nie mam mowy o Ramie

W kwestii wyjasnienia pojec. Tzw. zajetosc RAM nie ma zadnego znaczenia, mozesz uzyc 100% RAMu i program bedzie dziala poprawnie - oczywiscie jesli rozmiar fizyczny pamieci jest identyczny lub wiekszy niz rozmiar pamieci, ktora dysponuje linker. Nie mieszaj pojec!!! Zajetosc RAMu mowi tylko ile jeszcze zmiennych czy kodu mozesz dodac do swojego programu.

Czyli pobawmy sie we wrozke;)

  1. "Mazanie po pamieci" - uzywany wskaznik albo wsakzyje gdzie indziej niz myslisz badz przekroczyles rozmiar obiektu na ktory wskazuje wskaznik. Spojrz na mape linkera - gdzie zostala zaalokowana rzeczona zmienna tj. jaka zmienna znajduje sie przed nia.
  2. Uzyj grep i sprwadz wszystkie wystapienia inkryminowanej zmiennej - moze jednak jest modyfikowna explicite w kodzie.
  3. Czy nie zostal przekroczony rozmiar stosu. Na to ma wplyw glebokosc zgniezdzenia funkcji, ilosc zmiennych automatycznych trzymanych na stosie itp. a nie zajetosc RAMu przez program!!!

i najwazniejsze wyslac post na grupe pl.comp.lang.c ;)

Reply to
cepu69

Tue, 13 Oct 2009 14:37:54 +0200, na pl.misc.elektronika, Darkac napisał(a):

Popatrz na ewentualne bufory, których użycie odbywa się w runtime bez możliwości skontrolowania w kodzie : np. bufor do konwersji itoa, bufor odbiornika znakowej transmisji szeregowej itp.

Reply to
Jurek Szczesiul

Źle sparametryzowana biblioteczna funkcja printf potrafi zużyć dużo stosu. To taki przykład.

Za to kocham MSP430, w hardware-owym debugerze można ustawić pułapkę na zapis do obszaru pamięci i już wiadomo w wyniku jakiej instrukcji nastąpił problem. Sprawę rozwiązuje się w chwilkę.

A błędy na stosie mogą się markować bardzo długo a objawiać bardzo rzadko, akurat wtedy gdy nie trzeba. K.

Reply to
John Smith

Przeciez korzystajac z JTAG na ATMedze128 moze zrobic to samo...

Reply to
T.M.F.

Użytkownik "T.M.F." snipped-for-privacy@nospam.mp.pl> napisał w wiadomości news:hb2r8g$g8t$ snipped-for-privacy@nemesis.news.neostrada.pl...

Za to kocham JTAG.

Reply to
Ghost

To czemu tego autor wątku nie zrobi, a Wy nie doradzacie od początku? Już byłoby po problemie. K.

Reply to
John Smith

W dniu 14.10.2009 09:51, John Smith pisze:

Bo to wcale nie jest takie super narzedzie. Wyobraz sobie, ze zmienna ktora sledzisz jest modyfikowana w wielu miejscach i ciagle twoj program jest przerywany, mozna zeswierowac sledzac cos takiego.

Reply to
T.M.F.

Zajetosc RAM, ktora ci pokazuje kompilator moze sie miec nijak do rzeczywistego zapotrzebowania na pamiec. Przeciez kompilator nie pokazuje ci miejsca zajetego przez zmienne alokowane dynamicznie oraz na stosie.

Reply to
T.M.F.

Użytkownik "T.M.F." snipped-for-privacy@nospam.mp.pl> napisał w wiadomości news:hb46v6$5vf$ snipped-for-privacy@atlantis.news.neostrada.pl...

Dlatego też uważałem że potrzebny jest jakis margines bezpieczeństwa. Dlatego zrobiłem próbę ze zredukowanym radykalnie zapotrzebowaniem na RAM. Nie wiem w końcu jaką informację niesie pokazany przez kompilator stopień użycia RAM. Czy jest tam tylko to, co zajmują zadeklarowane zmienne globalne, czy też razem z maksymalną liczbą zmiennych lokalnych i stosem. Z powyższych odpowiedzi nie wynika to jednoznacznie. Może ktoś wypowie się.

A tak przy okazji zajętości RAM-u, nie wiem jak rozwiązać następujący problem: W programie jest sporo komunikatów tekstowych zadeklarowanych jako stałe w tablicach jednowymiarowych. Są one wyświetlane na LCD przez procedurę, której parametrem jest nazwa tablicy. Mimo że deklaracja tablic zawiera słowo "const", to stałe te niestety zajmują pamięć RAM. I to tyle bajtów ile w sumie liczą. Jak zrobić żeby stałe te były pobierane z pamięci programu we Flashu? Dlaczego powielane są do RAM-u? Czy słowo "const" oprócz zabezpieczenia przed zmianą nie powinno decydować o lokalizacji tej informacji?

Reply to
Darkac

A skąd kompilator ma wiedzieć ile Twój program w runtime zje stosu. Może zjeść i całą dostępną przestrzeń adresową, jeśli gdzieś go wpuścisz w stosowną pętelkę...

Reply to
DJ

AFAIR było wałkowane kiedyś już na grupie. Przeszukaj archiwum.

Reply to
DJ

formatting link
Michał

Reply to
invalid unparseable

Użytkownik "Michał Lankosz" snipped-for-privacy@tlen.pl napisał w wiadomości news:hb4bmb$t3a$ snipped-for-privacy@srv.cyf-kr.edu.pl...

Dzięki za linka. Prawdopodobnie to rozwiąże ten problem. Szkoda tylko że trzeba odwoływać się do różnych chytrych sztuczek żeby uzyskać, tak wydaje się, podstawowe i częste pożądane działania. Czasem odnoszę wrażenie, że jednak czasem komputer nie jest dla człowieka, a raczej człowiek dla komputera. Ostatnio mam do czynienia z procesorem DSP i środowiskiem do jego programowanie, gdzie nie jest przewidziany binarny sposób zapisu liczby. Jedynie dec lub hex. Prawdziwy horror, kiedy wciąż trzeba manipulować na pojedynczych bitach zmiennych czy rejestrów. A za to jest bardzo fajna właściwość, bo można zadeklarować zmienne pełniące rolę dwustanowych flag jako "bool". Podejrzewam, że nie zajmują wtedy całego bajtu. Jeśli tak , to przydało by się coś takiego w programowaniu ATmegi. Kupę RAM-u zajmują flagi. Duże marnotrawstwo. Bawienie się w maski, to znów przystosowywanie się do kaprysów komputera.

Reply to
Darkac

Oj, kłania się C...

formatting link

Reply to
DJ

Użytkownik "DJ" snipped-for-privacy@poczta.onet.pl> napisał w wiadomości news:hb4f5g$v2f$ snipped-for-privacy@news.dialog.net.pl...

Ale to przecież nic innego jak zabawa w maski. Stosowanie chytrych sztuczek i obiegnięć do osiągnięcia, wydawałoby się, prostego celu. Kompilator robi miliony różnych automatycznych operacji, mógłby robić również i to. Wszystko powinno być podporządkowane wygodzie człowieka. Po co zaśmiecać głowę i treść programu operacjami które może zrobić maszyna. Szybkość, łatwość i wygoda, to powinny być priorytety w pracy programisty.

Reply to
Darkac

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.