avr-gcc: Czy można wywołać ...

Witam!

Okazało się ze to nie był problem z wywoływaniem funckji z przerwań. To chyba co innego. Z nieznanych mi przyczyn jest istotna róznica jeśli:

a) Mam program w modułach b) definiuje zmienną globalną w jednym z modułów w postaci:

extern long zmienna (to w pliku .h) long zmienna (to w jednym z plików .c)

c) modyfikuje ją w przerwaniu

To w takiej konfiguracji zmiana "zmiennej" powoduje wesołe zawieszenie się reszty programu/błedne działanie.

jednak wystarczy zdeklarować:

static long zminna

A program się stabilizuje i działa poprawnie.

W kodzie wygląda to tak, że bez static allokowane jest to w innym obszarze niż ze static. Konkretnie static allokuje wyższe komórki (rzędu

0xd0) a ze static okolice 0x60.

Wygląda mi to dość dziwnie, tak jak gdyby nie dało się deklarować widocznych pomiedzy modułami zmiennych. Nie potrafie wyłapać dokladnych warunków, kiedy to zachodzi, ponieważ w róznych kombinacjach wielkości programu raz działa a raz nie działa (bez static). Ze static działa zawsze poprawnie.

Ktoś ma jakiś pomysł co robie źle ?

Reply to
Sebastian Bialy
Loading thread data ...

Dnia Fri, 01 Jul 2005 22:36:29 +0200, Sebastian Bialy snipped-for-privacy@poczta.onet.pl> napisał:

Hmm definicja w pliku naglowkowym jest w zasadzie "papierowa" jezeli mozna tak to nazwac. Przeciez kompilator powinien ja zrobic dopiero w miejscu wlaczenia do pliku .c

Hmm a includujesz ten sam plik .h? Moze jakis problem z overridami? Zrob moze definicje w .h warunkowa i ustawiaj odpowiedni warunek.

Reply to
Jaroslaw Berezowski

Ciagle nie widzie volatile :-)

Dziwne rzeczy piszesz. Jesli zmienna jest zadeklarowana poza funkcja, to "static" znaczy de facto "nie publiczna". Jako taka nie moze byc dostepna z innych modulow !

Kompilatora raczej nie podejrzewam .. albo uzywasz dwoch zmiennych w roznych modulach, albo masz konflikt nazw z biblioteka ..

POdeslij caly program.

J.

Reply to
J.F.

Fakt, zapomniałem dopisać, ale jest oczywiście.

W moim przypadku nie sięgam do niej z innych modułów (chwilowo) żeby wykluczyc jakies problemy między-modułowe. Jest deklarowana jako static i extern i korzysta z niej jeden i tem sam moduł. W jednym wypadku jest dobrze, w drugim dzieją się cuda.

Eeee :) Nie da rady, ale postaram się ten problem wywołać dla rzeczywistego kodu. na razie jedyny objaw to inna lokalizacja zmienne jw pamięci dla extern i static, natomiast w bardzo mayłym programie który korzysta z tego mechanizmu jest ok.

Będe dalej waczył.

Reply to
Sebastian Bialy

Maly test - skasuj static, ale zmien jej nazwe ..

Skasuj niepotrzebne czesci programu, ale zostaw zmienne - moze to pomoze odtworzyc blad.

J.

Reply to
J.F.

Już wiem, aczkolwiek jestem bardzo zdziwiony ...

Oczywiscie jestem temu winien. Mój program składa się z 5 modułów. Przypadkowo (zapewne efekt pisania nocami) w jednym z plików .c zapomniałem doinkludować charakterystyczme pliki do AVR. Ponieważ nie było w nim żadnych zaleznych sprzetowo elementów poza SIGNAL i matematyce na zmiennych to nie wrzeszczał o ich brak (swoją drogą bradzo dziwne, czyżby SIGNAL był wbudowany w avr-gcc ?).

Efekt: W tym jednym mudule zmienna lądowała w innym obszarze pamięci. Po dodaniu #include zmienna poleciała tam gdzie wszystkie.

Oczywiście wie ponosze ja, za nieuwagę, ale bardzo dzinym dla mnie zjawiskiem jaest fakt, że w ogóle kod się skompilował bez błędów.

Pisze to ku przestrodze, gdyby komus robily się również takie numery z lokalizacją zmiennych ...

Reply to
Sebastian Bialy

Sebastian Bialy napisał(a):

to wygląda tak, jakbyś sobie tą zmienną zadeklarował mimo wszystko w tym pliku. gdybyś nie miał wcześniej żadnej deklaracji, kompilator powinien się wywalić.

swoją drogą, dodajesz -Wall do flag kompilatora? dzięki dużej ilości ostrzeżeń łatwo wykryć potencjalne błędy.

w.

Reply to
Wojtek Kaniewski

Dziwne to co piszesz. Jesli zapomiales inlude ze zmienna, to powinno wywalic wielki blad ze zmienna niezdefiniowana. No chyba ze byla zdefiniowana w dwoch miejscach.

Natomiast SIGNAL .. bez include to jest po prostu zwykla funkcja o takiej nazwie, ktora kompiluje sie swietnie, ale wywolywana nigdy nie jest. Na assemblerze powinno cie zaciekawic:

-czemu nie konczy sie reti,

-czemu nie przechowuje uzywaneych rejestrow,

-czemu wektorek na nia nie wskazuje.

J.

Reply to
J.F.

Podziękuj Kernighanowi i Ritchiemu. :-)

Jeszcze lepszą zabawę będziesz miał, gdy uda Ci się wywołać konflikt nazwy Twojej funkcji z jedną z funkcji bibliotecznych

-- linker bez ostrzeżeia wybierze Twoją wersję, mimo, że inne fragmenty biblioteki moga chcieć się odwoływać do prawidłowej wersji. No cóż, jaki jest C każdy widzi...

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

nie chodzi o mój plik .h tylko w ogóle o zestaw plików .h:

avr/interrupt.h avr.signal.h arv/io.h ...

Dodaje ale wtedy, kiedy kod kompiluje mi się bez błędów, a w trakcie pisania programu na wczesnym etapie jest cała masa błędów typu "nieużyte i" albo "nigdy tego nie wywołasz" i tym podobnym. Więc wyłączyłem :) Ale masz rację, Wall mogło podpowiedziec co jest nie tak.

Reply to
Sebastian Bialy

Wyjasniłem jakie pliki h mi brakowało w sąsiednim poście.

Alez kończy, wcześniej tez kończyło się.

No własnie przechowywało wszystkie.

Moje zdumienie miało związek z faktem magicznego przenoszenia się zmiennej z 0x6x do 0xdx w zalezności od uzycia "static". Widocznie z jakiś powodów nie dołaczenie własciwych plików .h (moja wina) powoduje, że linker/kompilator allokuje zmienną w innym obszarze.

Teraz wszystko jest ok, i nie ma żadnych problemów.

Reply to
Sebastian Bialy

No niestety, tego typu "czeskie błędy" cały czas są moją zmorą. Ale C znam od 10 lat i na razie mimo jego upierdliwości nie zamienie go na nic innego, jeśli mam grzebac blisko sprzetu (a jak daleko, to C++).

A to akurat jest bardzo ok i w zasadzie zgodne ze zdrowym rozsądkiem jak dla mnie. Moim zdaniem pisanie programów w C jest swego rodzaju pozytywnym wyzwaniem szczególnie w czasach Delphi/VB i wszelkiej maści .NET ów, gdzie myślenie i znajomośc bebechów jest wysoce niewskazane.

Reply to
Sebastian Bialy

A to mnie zaciekawiło: dlaczego C++ stosujesz pisząc bardziej wysokopoziomowo, a C na niższym poziomie? Przecież wszystko, co można zrealizować w C przenosi się do C++ praktycznie bez modyfikacji, a w C++ dostajesz kilka bardzo silnych mechanizmów, m.in. szablony. Pokazałem Ci kilka dni temu w jaki sposób Twój nierozwiązywalny problem w C rozwiązać w kilku linijkach w C++, i to bez generowania jakiegokolwiek kodu i zajmowania pamięci.

Nie jest bardzo OK, bo może stać się przyczyną powstania bardzo trudnych do wykrycia błędów. W C++ można się przed tym zabezpieczyć za pomocą przestrzeni nazw

Pisanie programów w czymkolwiek nie jest żadnym wyzwaniem, to rzemiosło. Wyzwaniem jest zaprojektowanie programu, ale to się robi w oderwaniu od języka programowania.

To jakieś zabobony... :-) Języki trzymające się daleko od poziomu maszyny są równie potrzebne, jak te, które ujawniają niskopoziomową strukturę sprzętu -- każdy z nich ma swój obszar stosowalności.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Nie zrozum mnie źle, ale pisanie w kompilatorze C++ nie używając klas dalej uważam za pisanie w C. To że dostaje do rąk pare fajnych narzedzi (szablony na ten przykład jak sam wspomniałeś) jeszcze nie czyni ze mnie programisty C++ w tym przypadku. W zasadzie dla mnie pisanie w C++ to używanie klas/szblonów/STL. To się średnio nadaje do mikrokontrolerów

8-bitowych na razie. Tak więc po prostu inaczej definiuje "pisanie w C++"

Owszem, ale kiedyś pisałem bardzo dużo w assemblerze i swoboda grzebania po RAM była dla mnie bardzo ważną cechą. Kiedy przesiadłem się na C jęczałem na widok "niepotrzebnych" konwersji zmiennych, etc. Teraz kiedy przyszło mi nabazgrac plikację w Javie szlag mnie trafia na brak destrukorów, które są dla mnie ważne w C++. Każdy nastepny język ogranicza troche swobode (i dobrze, ogranicza to też błędy związane z prostymi pomyłkami) i coraz bardziej wymusza stosowanie czasochłonnych/pamięciochłonnych/zasobożernych rozwiązań, zamiast prostej podmiany funkcji bibliotecznej w C. Akurat tego nie stosuje powszechnie (2 razy w życiu :) acz zakładam, że są sytuację, kiedy się przydaje. Co nie znaczy że jestem przeciwnikiem języków myślących za programistów, ale po prostu jestem "wychowany" na asm Z80/6502/680x0/x86 i mam jakieś zboczenie w tym kierunku.

Cenie sobie C własnie dlatego że MOGĘ to zrobic. A to że czasami jest to źródłem błędu - no cóż, przy okazji jego rozwiązania uczę się. Inna sprawa, że przeciętny biznesmen powiedziałby, że trace czas na pierdoły. Więc zalezy to od punktu widzenia.

Hmmm, mam inne zdanie, a wyprowadzam je z mojej obserwacji wielu osób piszących programy. Przeciętny programista BASCOMa nie musi wiedziec nic na temat komunikacji układu X z Y - i to jest rzemiosło. Programista C w tej samej sytuacji zazwyczaj musi dośc dokładnie poznać dokuentację obydwu - i to jest wyzwanie. Pisanie w C/ASM w przypadku mikrokontrolerów to jedna większe wyzwanie niż w BASCOMie/etc.

Może BASCOM to zły przykład, ale w ogólnym przypadku pisanie w C wymaga od programisty znacznie więcej niż znajomosci paru funkcji wbudowanych w język. Z resztą nie trzeba daleko szukac, bo w wielu firmach pracują "programisci" pisząc przez pare lat programy skłądające się z kawałków truwialnego kodu w delphi przelatanych SQLem (w dodatku takich samych). To jest dopiero nuda i rzemiosło.

Reply to
Sebastian Bialy

Piotr Wyderski napisał(a):

szkoda, że tak późno zauważyłem tamten wątek, to bym napisał, że można po prostu zrobić tak:

unsigned long x;

if (sizeof(x) == sizeof(unsigned long)) { // foo }

if (sizeof(x) == sizeof(unsigned short)) { // bar }

gcc nawet bez -O już w trakcie kompilacji rozwinie sizeof() i usunie martwy kod warunkowy. fakt, to nie jest dokładne sprawdzanie typu (nie odróżni char[2] i short od unsigned short), ale w większości przypadków wystarczy.

w.

Reply to
Wojtek Kaniewski

A co jest złego w klasach, jeśli nie używa się funkcji wirtualnych i typowania dynamicznego? Przecież one się kompilują w _dokładnie_ taki sam sposób, jak struktury w C, a na poziomie języka dają kilka dodatkowych możliwości: dziedziczenie implementacji, szczegółowa kontrola dostępu do składowych itd.

Szczerze mówiąc to dość osobliwa definicja. ;-) Dla mnie pisanie w C++ polega na używaniu mechanizmów C++ -- a tutaj użycie klas i szablonów nie różni się niczym od tego, czego używa się na

64-bitowcu. Natomiast jeśli chodzi o STL, to go oczywiście na "maluchach" nie używam, ale nie ma przecież takiego obowiązku. Nawet standard języka wspomina na ten temat, wyróżniając środowiska hosted i freestanding.

Nie zawsze, kwestia przemyślenia struktury programu. Natomiast oddalenie się od maszyny wbrew pozorom bywa pomocne, bo dzięki temu środowiska uruchomieniowe mogą stosować takie transformacje kodu (zwłaszcza dynamiczne!), o których sobie w C++ można pomarzyć. Widziałem juz benchmarki, w których kod w Javie pobił wydajnością program w C++

-- wszystko dzięki optymalizacjom dynamicznym. Nawet mnie to kiedyś dość mocno interesowało, ale później zmieniłem kurs na specyfikowanie rozmaitych systemów i ich weryfikację.

Tylko żeby wówczas komuś nie urwało ręki na ten przykład...

Ja również, ale staram się nie przykładać jednej miarki do rozwiązań służących do zupełnie różnych celów. Są rzeczy, gdzie C++ pozwoli w doskonały sposób rozwiązać problem, a są i takie, gdzie to będzie horrorem, natomiast inne narzędzie pozwoli na wygodne zapisanie rozwiązania. Przyroda jest przebogata i należy z tego korzystać, a nie ograniczać się do jednego rozwiązania jednego sposobu myślenia. Liczba istniejących języków programowania jest dowodem, że nie istnieje coś takiego, jak najlepszy język. Są tylko mniej lub bardziej dobre do rozwiązywania problemów ze ściśle określonej dziedziny. Jeśli tą dziedziną jest programowanie niskopoziomowe, to C jest dobre, a C++ bardzo dobre, więc trochę dziwi mnie, że podchodzisz do tego ostatniego jak do jeża -- mity o rzekomej złożoności kodu wynikowego wyprodukowanego przez kompilator C++ skutecznie rozwiewa zapoznanie się z listingami disasemblera. Wiele kompilatorów (w tym GCC) ma wspólny optymalizator i generator kodu dla wielu języków programowania -- w takich przypadkach to nie są nawet mity, ale zwyczajne bzdury.

Wprost z ust mi to wyjąłeś. ;-P

Zgoda, ale to się robi podczas projektowania programu, a nie jego implementowania (choć oczywiście te dwie fazy mogą się ze sobą przeplatać). Gdyby taki przemyślany program zapisać w Bascomie, to również doskonale zadziała. Programowanie w C albo czymkolwiek innym żadnej nowej jakości nie dodaje.

Z resztą się zgadzam.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Ależ o te własnie wirtualne chodzi :) Co mi po klasach, które nie dają w zasadzie nic ciekawego do kodu poza pewnym porzadkowaniem metod+danych. Z resztą co do klas - troche głupio ich uzywać nie mając pod ręką operatorów new/delete, wyjątków czy poprawionych includów (mówie teraz o AVR-GCC). Na razie AVR-GCC nie jest dobrym pomysłem do pisania w C++.

Choć już za chwile, juz za momencik zamierzam zawalczyć z ARM i rozpasanymi przestrzeniami RAM rzędu 128kB :)

Akurat Java i C++ to żadne różnica, prawie identyczny zapis, prawie identyczne zastosowanie (poza przenośnym kodem wynikowym). Dla programisty tak samo się pisze w obydwu. Z resztą teraz mam troche dłubania w Javie (OpenGL) i jestem pod wrażeniem, że w zasadzie chodzi tak samo jak kod natywny (jest fajna wersja QuakeII pod Javę :).

Jednak ponieważ rozmawiamy o uC w końcu, to dalej nie wiem, czy jest sens stosowania języków _za wysokiego_ poziomu do uC. Tam często trzeba dlubac po rejestracj/pamięci albo liczyć cykle czy stosować sztuczki przedziwne żeby zmniejszyć ilość instrukcji asm. Chyba nie ma chwilowo nic lepszego niż C do pisania programów na uC. Mam na mysli jakies większe projekty, a nie miganie diodą w BASCOMIE w delach dydaktycznych. Oczywiście BASCOM rulez ale czy ktoś napisal w nim obsługe FAT na MMC czy jakiś algorytm szyfrujący ?

No bez przesady :) takie błędy też można znaleźć w sofcie każdym. Z resztą jakoś ludzie piszą w C aplikacjie bardzo powazne i nie ma kłopotu :)

Jestem ciekawy co wypluje gcc po kompilaci kodu z obiektami i metodami wirtualnymi :) Trzeba będzie się poświęcić dla sztuki i pobawić obiektami na ATTiny ... Swoją drogą od dawna pisze obiektowo i czuje się troche jak bez ręki przy dłubaniu w czystym C ...

Jasne, że każdy problem można zapisać równie dobrze w każdym języku, jednak nie w każdym optymalnie i nie w każdym jest baza gotowych rozwiązań. Z resztą BASCOM chyba nie powstał po to, aby pisać w nim wielkie projekty na uC, widać to po składni.

A to ja już nic nie pisze wobec tego w tej odnodze. EOT :) Pozdrawiam.

Reply to
Sebastian Bialy

Niemozliwe - 'SIGNAL' nie jest wbudowane w kompilator. Przynajmniej w wersji 20050214. Bez io.h masz nawet niezdefiniowane nazwy przerwan - to gdzie ma wstawic wektor ?

Jest to mozliwe. Ale nie powinno miec wiekszego wplywu na dzialanie.

J.

Reply to
J.F.

No - trzeba przyznac ze Piotr swego czasu podal kilka rzeczowych argumentow, ktore imho nie mialy wiekszego znaczenia praktycznego .. ale chyba wlasnie sie na dwa z nich nadziales :-)))

J.

Reply to
J.F.

Nie bardzo - nie zrozumiales dokladnie o co chodzi. a) wpisujemy w zrodlo czestotliwosc kwarcu, w #define b) kompilator na jej podstawie sam wylicza potrzebne wartosci c) w zaleznosci od tego co wyjdzie uzywa w kodzie arytmetyki typu int lub long.

Tymczasem u ciebie:

0) i tak nie wyliczysz tej wartosci, bo to ponad mozliwosci preprocesora C. 1) nie zadeklarujesz potrzebnych zmiennych roznych typow w zaleznosci od wynikow obliczen. 2) o ile zadziala to na zmiennych, to na stalych nie. sizeof(1000*500) wynosi .. 2

J.

Reply to
J.F.

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.