Jak skonfigurować AVR-GCC w AVR Studio i rozwiązać problemy z kompilacją?
do ekspertow od AVR-GCC
From: "Jerzy Spyrka" <jspyrka_at_nospam_poczta.onet.pl>
Subject: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 10:11:18 +0100
Witam Wszystkich !!!
Do tej pory pisalem programy na AVRy w assemblerze i nawet sobie radzilem.
Postanowilem jednak sprobowac C. Moj wybor, jesli chodzi o kompilator, padl
oczywiscie na AVR-GCC, ze wzgledu na cene, lub raczej jej brak ;-). Nie
jestem informatykiem, a swoja wiedze posiadlem raczej z samouctwa i domyslow
niz z fachowej literatury. Stad pewnie przyczyna gnebiacych mnie
niejasnosci, szczegolnie w zakresie kompilacji, linkowania itd. Mam
nadzieje, ze Koledzy Grupowicze pomoga mi rozwiac te niejasnosci.
Pierwsza sprawa to samo uruchomienie srodowiska do "zabawy". Z AVRfreaks.net
sciagnalem ostatnia wersje kompilatora 3.2 (a konkretnie
"2002-06-25_FREAKS.exe"). Zastosowalem sie do rad jak sprzegnac to z AVR
Studio (proponowana wersja 3.53), i rozpoczalem poznawanie od przykladow
zawartych w katalogu "GCCTEST". Niestety nie udalo mi sie poprawnie
skompilowac zawartych tam przykladow (poza bodajze "gcctest6"). Wyskakiwal
komunikat "Errors detected during link stage" a wczesniej zglaszony zostal
blad "C:\AVRGCC\BIN\MAKE.EXE: * [gcctest1.cof] Error 256". Ale co ciekawe
generowany jest poprawny plik .hex do zaprogramowania AVRa.
Tu pierwsze moje pytanie - czy mozna temu zaradzic?
Nie zniechecony niepowodzeniem postanowilem odinstalowac wersje 3.2 AVR-GCC
i zainstalowalem wersje 3.0.2 ("avrgcc_freaks20011214a.exe"). W tym
przypadku udalo mi sie zmontowac srodowisko z AVR Studio. Poza ostatnim
"gcctest9" reszta przykladow kompiluje sie poprawnie.
Rozpoczalem wiec zabawe z pierwszym przykladem ("gcctest1"). Wszystko dziala
OK. Ledy migaja. Czyli efekt zostal osiagniety. Ale ja, ze wzgledow
edukacyjnych, postanowilem przyjrzec sie temu programowi od srodka i przy
pomocy debuggera przesledzic co naprawde tam sie dzieje. A dzieje sie rzecz
nie pojeta przez moja "assemblerowa" glowe. Ale po kolei. Zamieszczam pod
spodem zrodlo w C:
#include <io.h>
typedef unsigned char u08;
int main( void )
{
u08 led, i, j, k;
outp(0xff,DDRB); /* use all pins on PortB for output */
led = 1; /* init variable representing the LED state
*/
for (;;) {
outp(~led, PORTB); /* invert the output since a zero means: LED
on */
led <<= 1; /* move to next LED */
if (!led) /* overflow: start with Port B0 again */
led = 1;
for (i=0; i<255; i++) /* outer delay loop */
for(j=0; j<255;j++) /* inner delay loop */
k++; /* just do something - could also be a NOP */
}
}
Jak widac program jest niezwykle prosty. Zaswieca po kolei ledy (podpiete do
PORTB) na czas trwania petli opozniajacych i w przypadku dojscia do
ostatniej diody, na powrot zapala diode pierwsza.
Moje spostrzezenie dotyczy petli opozniajacych:
for (i=0; i<255; i++) /* outer delay loop */
for(j=0; j<255;j++) /* inner delay loop */
k++; /* just do something - could also be a NOP */
Zadeklarowano zmienne i, j, k. Kompilator, swoim prawem, przydzielil
zmiennej "i" rejestr "r25", zmiennej "j" - "r24", a zmiennej "k" nie
przydzielil zadnej komorki pamieci - dlaczego?
Ponizej jest zdeassemblerowany z wyjsciowego pliku .hex fragment realizujacy
powyzsze petle opozniajace
+00000037: E090 LDI R25,0x00 ; 0x00 = 0b00000000 = 0
+00000038: E08F LDI R24,0x0F ; 0x0F = 0b00001111 = 15
+00000039: 3F8F CPI R24,0xFF ; 0xFF = 0b11111111 = 255
+0000003A: F418 BRCC +0x03 ; Destination: 0x00003E
+0000003B: 5C84 SUBI R24,0xC4 ; 0xC4 = 0b11000100 = 196
+0000003C: 3F8F CPI R24,0xFF ; 0xFF = 0b11111111 = 255
+0000003D: F3E8 BRCS -0x03 ; Destination: 0x00003B
+0000003E: 5F9F SUBI R25,0xFF ; 0xFF = 0b11111111 = 255
+0000003F: 3F9F CPI R25,0xFF ; 0xFF = 0b11111111 = 255
+00000040: F3B8 BRCS -0x09 ; Destination: 0x000038
Po przeanalizowaniu tego kodu widac, ze faktycznie logika zawarta w zrodle C
jest realizowana (z wyjatkiem braku zwiekszania zmiennej "k", krorej w
rzeczywistosci po prostu nie ma), ale tylko logika bo wartosci zmiennej "j"
sa dziwne. Owszem zmienna "i" zmienia wartosc od 0-255 ze skokiem 1, ale
zmienna "j" NIE zmienia wartosci jak podano z zrodle C od 0-255 ze skokiem
1. Faktycznie jest tak, ze zmienna "j" zmienia wartosci od 15-255 ze skokiem
60 (256-196=60).
Dlaczego tak jest? Czy "j++" nie zmienia wartosci o jeden jak w przypadku
"i++"? Czy ten skok gdzies sie ustala?
To tyle. Przepraszam za zbyt dlugi post. Mam nadzieje, ze szanowni
Grupowicze udziela mi odpowiedzi na moje pytania.
Z gory dziekuje i pozdrawiam
Jurek
ps.
Gdzie poczytac na temat kompilatora, albo jak dobrac sie do informacji
zawartych w katalogu "avrgcc\man", chyba cos tam jest?, pracujac pod windows
a nie linux.
From: "Andy" <anok_at_nospam_ceti.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 10:47:58 +0200
"Jerzy Spyrka" <jspyrka_at_nospam_poczta.onet.pl> wrote in message news:agjefd$g99$1_at_nospam_news.tpi.pl...
...
Moje spostrzezenie dotyczy petli opozniajacych:
for (i=0; i<255; i++) /* outer delay loop */
for(j=0; j<255;j++) /* inner delay loop */
k++; /* just do something - could also be a NOP */
Zadeklarowano zmienne i, j, k. Kompilator, swoim prawem, przydzielil
zmiennej "i" rejestr "r25", zmiennej "j" - "r24", a zmiennej "k" nie
przydzielil zadnej komorki pamieci - dlaczego?
...
jesli z mienna "k" nie jest oprocz tego miejsca nigdzie
uzywana to moze kompilator tak zoptymalizowal, ze ja "zjadl"
uznal, ze jej zwiekszanie nie ma zadnego wplywu na dzialanie programu
(oprocz wplywu czasowego)
trzeba zmienna "k" zadeklarowac jako "volatile" to wtedy
nie powinien jej zjesc
...
Dlaczego tak jest? Czy "j++" nie zmienia wartosci o jeden jak w przypadku
"i++"? Czy ten skok gdzies sie ustala?
...
j++ zawsze daje skok o 1
niegdzie sie nie ustala jesli potrzebujesz wiecej
to np. j += 5 daje skok o 5
Andrzej
From: zielpro_at_nospam_cavern.pl (ziel)
Subject: RE: do ekspertow od AVR-GCC
Date: 11 Jul 2002 11:56:23 +0200
int main( void )
{
for (;;)
{
if (!led) /*
for (i=0; i<255; i++) /* outer
for(j=0; j<255;j++) /* inner
k++; /* just
}
}
Ja tam się nie znam, ale mnie brakuje klamerek.
pzdr
Artur
--
Archiwum grupy: http://niusy.onet.pl/pl.misc.elektronika
From: "Andy" <anok_at_nospam_ceti.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 12:57:29 +0200
Użytkownik "ziel" <zielpro_at_nospam_cavern.pl> napisał w wiadomości
news:DOELJDHHJKPIEKPIGAMEGEFFDIAA.zielpro_at_nospam_cavern.pl...
int main( void )
{
for (;;)
{
if (!led) /*
for (i=0; i<255; i++) /* outer
for(j=0; j<255;j++) /* inner
k++; /* just
}
}
Ja tam się nie znam, ale mnie brakuje klamerek.
pzdr
Artur
przy jednym wierszu nie potrzebne jesli w porzednim nie ma srednika na koncu,
mozna to zapisac tak:
if (!led) for (i=0; i<255; i++) for(j=0; j<255;j++) k++;
Andrzej
From: "Andy" <anok_at_nospam_ceti.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 13:00:40 +0200
Użytkownik "Andy" <anok_at_nospam_ceti.pl> napisał w wiadomości
news:2117-1026384839_at_nospam_main.lokalizuj.auto.pl...
Użytkownik "ziel" <zielpro_at_nospam_cavern.pl> napisał w wiadomości
news:DOELJDHHJKPIEKPIGAMEGEFFDIAA.zielpro_at_nospam_cavern.pl...
int main( void )
{
for (;;)
{
if (!led) /*
for (i=0; i<255; i++) /* outer
for(j=0; j<255;j++) /* inner
k++; /* just
}
}
Ja tam się nie znam, ale mnie brakuje klamerek.
pzdr
Artur
przy jednym wierszu nie potrzebne jesli w porzednim nie ma srednika na koncu,
mozna to zapisac tak:
if (!led) for (i=0; i<255; i++) for(j=0; j<255;j++) k++;
Andrzej
sory
nie do konca tak bo cytat byl za bardzo przyciety,
mam byc tak i tak bylo w pierwszym poscie
if (!led) led = 1;
for (i=0; i<255; i++) for(j=0; j<255;j++) k++;
Andrzej
From: zielpro_at_nospam_cavern.pl (ziel)
Subject: RE: do ekspertow od AVR-GCC
Date: 11 Jul 2002 22:58:39 +0200
nie do konca tak bo cytat byl za bardzo
przyciety,
mam byc tak i tak bylo w pierwszym poscie
if (!led) led = 1;
for (i=0; i<255; i++) for(j=0; j<255;j++)
k++;
Andrzej
Czyli, że k jest (o ile jest bajtem) kopią i,
a pętla j wykonuje się w całości dla każdego i.
A może k jest kopią j?
Właśnie sobie prześledziłem i k nie jest niczyją
kopią.
A w takim wypadku znając fantazję programistów C
kompilator nie ma prawa pomijać k, no chyba, że
kompilator
zna absolutnie wszystkie możliwe metody i może na
100%
wykluczyć dostęp do k w tym programie.
Zdecydowanie wolę pisać z klamerkami.
pzdr
Artur
--
Archiwum grupy: http://niusy.onet.pl/pl.misc.elektronika
From: "Zbych" <bzb_at_nospam_poczta.onet.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 23:25:56 +0200
no chyba, że
kompilator
zna absolutnie wszystkie możliwe metody i może na
100%
wykluczyć dostęp do k w tym programie.
Po prostu wartość zmiennej k nie jest nigdzie
używana W SPOSÓB JAWNY i w czasie
optymalizacji została ona usunieta.
A to, że czasem usuwane są
całkiem ważne fragmenty programu to
jeszcze jeden powód żeby do zabawy
używać IARa (wersja demo jest tu zupełnie
wystarczająca).
Zdecydowanie wolę pisać z klamerkami.
A to już kwestaja gustu.
From: "Andy" <anok_at_nospam_ceti.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 00:53:07 +0200
"ziel" <zielpro_at_nospam_cavern.pl> wrote in message
news:DOELJDHHJKPIEKPIGAMEEEHDDIAA.zielpro_at_nospam_cavern.pl...
nie do konca tak bo cytat byl za bardzo
przyciety,
mam byc tak i tak bylo w pierwszym poscie
if (!led) led = 1;
for (i=0; i<255; i++) for(j=0; j<255;j++)
k++;
Andrzej
Czyli, że k jest (o ile jest bajtem) kopią i,
a pętla j wykonuje się w całości dla każdego i.
A może k jest kopią j?
Właśnie sobie prześledziłem i k nie jest niczyją
kopią.
"k" nie moze byc niczyja kopia
to zupelnie odrebna zmienna
tylko trudno przewidziec jej wartosc poniewaz nie
jest zainicjowana
gdyby kompilator nie dokonal optymalizacji
to "k" powinno byc inkrementowane 255 * 255 = 65025 razy
bez wzgledu na to czy z klamerkami czy bez
A w takim wypadku znając fantazję programistów C
kompilator nie ma prawa pomijać k, no chyba, że
kompilator
zna absolutnie wszystkie możliwe metody i może na
100%
wykluczyć dostęp do k w tym programie.
Zdecydowanie wolę pisać z klamerkami.
pisanie z klamerkami daje efekt optyczny
nie sadze (pewien nie jestem), zeby to cos zmienilo
w optymalizacji
i tak "zezre" k jesli nie bedzie "volatile"
Andrzej
From: zielpro_at_nospam_cavern.pl (ziel)
Subject: RE: do ekspertow od AVR-GCC
Date: 12 Jul 2002 02:01:34 +0200
"k" nie moze byc niczyja kopia
to zupelnie odrebna zmienna
tylko trudno przewidziec jej wartosc
poniewaz nie
jest zainicjowana
Zakładając, że k ma na początku wartość 0
w CodeVision k w każdej następnej pętli ma wartość
o 1
większą od j.
gdyby kompilator nie dokonał optymalizacji
to "k" powinno być inkrementowane 255 *
255 = 65025 razy
To może ja to źle czytam?
Bo na symulacji wychodzi coś innego.
bez wzgledu na to czy z klamerkami czy bez
Ale z klamerkami dokładnie widać co poeta ma na
myśli.
pisanie z klamerkami daje efekt optyczny
nie sadze (pewien nie jestem), zeby to
cos zmienilo
w optymalizacji
i tak "zezre" k jesli nie bedzie "volatile"
No to, do d... z taką optymalizacją.
pzdr
Artur
--
Archiwum grupy: http://niusy.onet.pl/pl.misc.elektronika
From: Ireneusz Niemczyk <i.niemczyk_at_nospam_multispedytor.com.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 18:38:02 +0200
Arturze, nie ma sensu porównywać różne kompilatory...po prostu proces
optymalizacji może doprowadzić do zupełnie innych wyników symulacji
(pamiętaj że rozmawiamy o szczegółach).
Zamierzeniem autorów z GCC było pewnie zrobienie czegokolwiek....coś ala
NOP. Na nieszczęście dla tego przykładu optymalizacja zjadła ich zamiar
- może zapomnieli uczulić kompilator na tš zmiennš, a może kolejna
wersja GCC posiadła optymalizację pozwalajšcš na usunięcie nieużywanej
zmiennej, a autorzy po prostu o nie pomyśleli żeby zmienić przykład.
Tak czy siak, moim skromnym zdaniem świadczy to dobrze o optymalizacji
-)
--
PZD, Irek.N.
From: zielpro_at_nospam_cavern.pl (ziel)
Subject: RE: do ekspertow od AVR-GCC
Date: 12 Jul 2002 21:51:06 +0200
Zamierzeniem autorów z GCC było pewnie
zrobienie czegokolwiek....coś ala
NOP.
Na nieszczęście dla tego przykładu
optymalizacja zjadła ich zamiar
- może zapomnieli uczulić kompilator na
tš zmiennš, a może kolejna
wersja GCC posiadła optymalizację
pozwalajšcš na usunięcie nieużywanej
zmiennej, a autorzy po prostu o nie
pomyśleli żeby zmienić przykład.
Tak czy siak, moim skromnym zdaniem
świadczy to dobrze o optymalizacji
-)
--
> PZD, Irek.N.
>
>
Może i dobrze, ale ten sam program na CV zachowuje
się inaczej,
a to już wymaga od piszącego znajomości niuansów
dwóch programów.
Oczywiście po roku siedzenia nad CV, chcąc napisać
jakiś program,
zrobię to bez problemu. Problem powstanie kiedy
weźmie górę moje
lenistwo i wkleję kawałek kodu pisany np. w GCC.
Ech, życie, nic nie ma lekko :-(
pzdr
Artur
--
Archiwum grupy: http://niusy.onet.pl/pl.misc.elektronika
From: jfox_at_nospam_poczta.onet.pl (J.F.)
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 17:55:31 GMT
On 11 Jul 2002 22:58:39 +0200, ziel wrote:
if (!led) led = 1;
for (i=0; i<255; i++) for(j=0; j<255;j++) k++;
A może k jest kopią j?
Właśnie sobie prześledziłem i k nie jest niczyją
kopią.
W zasadzie mozna policzyc o ile sie k zmieni po tych petlach.
tylko maly problem - k nie jest zainicjowane .
A w takim wypadku znając fantazję programistów C
kompilator nie ma prawa pomijać k, no chyba, że
kompilator zna absolutnie wszystkie możliwe metody i może na
100% wykluczyć dostęp do k w tym programie.
Ma swiete prawo - w koncu nigdzie wiecej k sie nie pojawia ..
Zdecydowanie wolę pisać z klamerkami.
Nic nie zmienia. Nawet czytelnosc nie zawsze sie polepsza ..
J.
pzdr
Artur
From: Adam Dybkowski <adybkows_at_nospam_amwaw.edu.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Thu, 11 Jul 2002 19:26:26 +0200
Jerzy Spyrka wrote:
Zadeklarowano zmienne i, j, k. Kompilator, swoim prawem, przydzielil
zmiennej "i" rejestr "r25", zmiennej "j" - "r24", a zmiennej "k" nie
przydzielil zadnej komorki pamieci - dlaczego?
[...]
Dlaczego tak jest? Czy "j++" nie zmienia wartosci o jeden jak w przypadku
"i++"? Czy ten skok gdzies sie ustala?
Standardowe zagadnienie - dobry optymalizer w avr-gcc optymalizuje
wszystko az do bolu. Jezeli inkrementujesz 100 razy jakas zmienna to
zostanie ona po prostu od razu zwiekszona o 100. Musisz stosowac
magiczne slowo 'volatile' w takich przypadkach.
--
Adam Dybkowski
adybkows_at_nospam_amwaw.edu.pl
http://www.amwaw.edu.pl/~adybkows
From: "Jerzy Spyrka" <jspyrka_at_nospam_poczta.onet.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 09:59:31 +0100
Dzieki za odpowiedz.
Nie myslalem, ze drobny programik dolaczony jako przyklad (gcctest1) do
pakietu AVR-GCC wywola taka dyskusje. Swoja droga to troche glupio, ze
kompilator optymalizuje wszystko na full. Ale ja sie nie znam na jezykach
wysokiego poziomu - maja swoje prawa. Jak zadeklaruje sobie cos w
assemblerze, to to mam i wiem gdzie tego szukac, a tutaj masz, czlowiek chce
sie uczyc, bierze przyklad, i moze sobie szukac jakiejs tam zmienej "k".
Strach pomyslec co bedzie przy pisaniu naprawde czegos duzego, jak w trakcie
debuggowania wyjdzie (albo i nie), ze wcielo gdzies kilka zadeklarowanych
zmiennych.
I taki wniosek na koniec. Czy faktycznie nie lepszy assembler? Tam wszystko
wiadomo co i kiedy sie dzieje. Ale jak komus zalezy na czasie... zostaje np.
C z jego prawami.
To tyle.
Jeszcze raz dzieki. Pozdrowienia
Jurek
From: "Andy" <anok_at_nospam_ceti.pl>
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 12:18:51 +0200
"Jerzy Spyrka" <jspyrka_at_nospam_poczta.onet.pl> wrote in message news:agm27c$m42$1_at_nospam_news.tpi.pl...
...
Jak zadeklaruje sobie cos w
assemblerze, to to mam i wiem gdzie tego szukac, a tutaj masz, czlowiek chce
sie uczyc, bierze przyklad, i moze sobie szukac jakiejs tam zmienej "k".
-)
kompilator C ma wiele opcji optymalizacji
co ma gcc to nawet dokladnie nie wiem
zawsze mozna powylaczac optymalizacje
ale optymalizacje sa po to, zeby bylo troche lepiej niz bez :-)
albo program krotszy albo troche szybciej chodzacy itp
np Keil C na 51 ma 9 opcji optymalizacji
Strach pomyslec co bedzie przy pisaniu naprawde czegos duzego, jak w trakcie
debuggowania wyjdzie (albo i nie), ze wcielo gdzies kilka zadeklarowanych
zmiennych.
dokladnie tak bywa
ale jak sie o tym wie to zwykle daje sie zapanowac
I taki wniosek na koniec. Czy faktycznie nie lepszy assembler? Tam wszystko
wiadomo co i kiedy sie dzieje. Ale jak komus zalezy na czasie... zostaje np.
C z jego prawami.
do pewnych rzeczy lepszy asembler do pewnych C albo i cos innego
ja znam tylko asm i C
Andrzej
From: jfox_at_nospam_poczta.onet.pl (J.F.)
Subject: Re: do ekspertow od AVR-GCC
Date: Fri, 12 Jul 2002 17:55:33 GMT
On Thu, 11 Jul 2002 10:11:18 +0100, Jerzy Spyrka wrote:
Moje spostrzezenie dotyczy petli opozniajacych:
for (i=0; i<255; i++) /* outer delay loop */
for(j=0; j<255;j++) /* inner delay loop */
k++; /* just do something - could also be a NOP */
Zadeklarowano zmienne i, j, k. Kompilator, swoim prawem, przydzielil
zmiennej "i" rejestr "r25", zmiennej "j" - "r24", a zmiennej "k" nie
przydzielil zadnej komorki pamieci - dlaczego?
Optymalizujacy ? k nigdzie wiecej w programie nie uzywane, to mozna
pominac. Inna sprawa ze wszystko powyzej moglby pominac :-)
Po przeanalizowaniu tego kodu widac, ze faktycznie logika zawarta w zrodle C
jest realizowana (z wyjatkiem braku zwiekszania zmiennej "k", krorej w
rzeczywistosci po prostu nie ma), ale tylko logika bo wartosci zmiennej "j"
sa dziwne. Owszem zmienna "i" zmienia wartosc od 0-255 ze skokiem 1, ale
zmienna "j" NIE zmienia wartosci jak podano z zrodle C od 0-255 ze skokiem
1. Faktycznie jest tak, ze zmienna "j" zmienia wartosci od 15-255 ze skokiem
60 (256-196=60).
Ciekawe - czyzby na tyle optymalizatorowi pamieci starczylo ? Potrafil
60 obiegow petli przesledzic i zmienic w jeden, dopasowal tylko
wartosc startowa zeby po petli bylo dobrze ?
Z ciekawosci wstawilbym {k++; m++} w petli i zobaczyl co z tego
wyjdzie .. albo jak sobie poradzi gdyby zamiast j<255 wstawic
j<50 ..
Gdzie poczytac na temat kompilatora, albo jak dobrac sie do informacji
zawartych w katalogu "avrgcc\man", chyba cos tam jest?, pracujac pod windows
a nie linux.
Nie ma gdzies programu "info" ?
J.