RTV forum PL | NewsGroups PL

Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

Dziwne zachowanie kompilatora w AVRGCC.

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

Piotr Wyderski
Guest

Wed May 05, 2004 7:08 pm   



Milosz Skowyra wrote:

Quote:
Juz sam wiem, olalem warninga kompilatora i zapomnialem o zrzutowaniu
wskaznika na integera Wink

Wcale nie, to Ty nie przeczytales tego warninga i nie zamieniles
integera na char*. Przykro mi, dopisujac "brakujace" rzutowanie
Ty nie naprawiles tego programu, Ty zgwalciles kompilator. :->

Pozdrawiam
Piotr Wyderski

Milosz Skowyra
Guest

Thu May 06, 2004 8:20 am   



Piotr Wyderski wrote:

Quote:
Scisle rzecz biorac nie popelniasz bledu, ale napisales
kompilatorowi nie ten program o ktorym myslales. Smile
Kazesz mu wziac adres poczatku f-tej _tablicy_, a
nie adres f-tego _elementu_ tej tablicy. Natomiast to
0x31 do niczego mi nie pasuje: masz 49 elementow w tablicy?

Tia, w probnej wersji bylo tylko 49 elementow. Teraz juz kumkam.

Quote:
PS. Cos wspominales o przejsciu na uprawe marchewki. Wink))

Wlasnie kombajn do zbiorow konstruuje Wink)

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Thu May 06, 2004 8:24 am   



"J.F." wrote:

Quote:
a nie mogl bys tej tablicy jakos po ludzku indeksowac ? Smile
polish_chars[ f ]
Tylko ze nie bardzo chce dzialac Wink
W R14 i R15 jest adres poczatku tablicy.

MOV R31,R15
MOV R30,R14 ;to niby poprawnie, do Z wpisuje pocz.tablicy
LD R24,Z+ ;w dziwny sposob zwieksza Z o jeden i czyta

Ta dziwnosc moze byc sprytnoscia - jesli rozpoznal ze w kolejnych
obiegach petli siegasz do kolejnych komorek pamieci, to jest
to prawidlowa kompilacja.

Bez przesady, szybciej bedzie mu zrobic adiw z,1 bo nie bedzie przelewal
Z w rejestry tam i spowrotem.

Quote:
;bajt z RAMU spod adresu poczatku tablicy w ROM
MOV R14,R30 ;zrzuca adres tablicy +1
MOV R15,R31
MOV R30,R24 ;i gdyby nie wykonal tego to LPM odczytalo by
CLR R31 ;poprawna wartosc, a tak dostajemy krzaczki.
LPM

A nie przekombinowales znowu ? Moze masz
lcd_port=pgm_read_byte(polish_chars[f]);

Dokladnie tak, bo tak sugerowal Andy ;-)

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Thu May 06, 2004 8:53 am   



"J.F." wrote:

Quote:
b) kolega przekombinowal [a raczej nie przeczytal pewnej ksiazki Smile]
Czytam powoli... i podpieram sie dodatkowo kieszonkowym leksykonem C++.
Czytac szybciej, szczegolnie rozdzial arytmetyka wskaznikow Smile

Robi sie... problem tylko ze co innego czytalem a co innego rozumialem
;-(((
Znaczy sam sie w pole (marchewki) wyprowadzilem.

[...]
Quote:
Z sensem wygladaloby to tak:
char *x; //wskaznik
x=&polish_chars; //teraz wskazuje na poczatek tablicy
x+=3 //teraz wskazuje na 4 znak tablicy
*x+=5 // a teraz ten znak powiekszamy o 5
Gdyby w tablicy bylo "ABCDEFGHI", to po wykonaniu zrobiloby sie
"ABCIEFGHI" ... gdyby to nie byl ROM.

I juz kumam. Nie wiem dlaczego ale caly czas lazilo mi po glowie ze jak
operujemy na wskazniku to na wskazniku, czyli jak mamy char *x; to
wszystkie operacje tycza sie *x. Teraz wiem ze operacje na zawartosci
wskazywanej zmiennej odbywa sie przez dereferencje.
Jeszcze ostatnia niejasnosc...
char x[20],y[20],a;
char *xptr;
xptr=&x; //######
a=*xptr; //w a laduje element x[0]

xptr=&x+1; //######
a=*xptr; //w a laduje element y[0]

xptr=x;
a=*xptr; //w a laduje element x[0]

xptr=x+1;
a=*xptr; //w a laduje element x[1]

juz mysle dobrze czy nadal gdzies blad w logice ??
I jeszcze jedno. Kompilacja tego powyzej daje w liniach oznaczonych
##### warninga
"main.c:16: warning: assignment from incompatible pointer type". Mam
racje ze chodzi o to ze 2 bajtowy pointer nie miesci sie w char-ze ??

Quote:
Bo polish_chars jest tablica, i rozmiar ma chocby i 64.
Ale &polish_chars jest juz tylko adresem, a ten liczy 2 bajty.
Natomiast kompilator pamieta na co &polish_chars wskazuje,
wiec &polish_chars+1 to bynajmniej nie jest ten sam adres
co polish_chars+1.

To chyba wlasnie pojalem ;-)

Quote:
A swoja droga - o ile kompilator pozwala zdefiniowac taka tablice
w obszarze pgm, to imho powinien poprawnie komplilowac po prostu
polish_chars[f] - albo cos o tym pisze w faq, albo trzeba serwis
powiadomic..

Jak dziala polish_chars[f] to juz podalem ;-)

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

J.F.
Guest

Thu May 06, 2004 9:41 am   



On 05 May 2004 21:17:26 +0200, Jan Dubiec wrote:
Quote:
Aha - to dotyczy rzeczywistej deklaracji tablicy, bo
deklaracja w naglowku funkcji jest wskaznikiem..
Nie bardzo rozumiem. Może jakiś przykład?


Quote:
int test(char tab1[10])
{
char *tab2, **tp1, **tp2;
tp1 = (char**) &tab1;
tp2 = &tab2;
printf("tab1=%p, tp1=%p, *tp1=%p\n", tab1, tp1, *tp1);
printf("tab2=%p, tp2=%p, *tp2=%p\n", tab2, tp2, *tp2);

tab2 = tab1;
printf("tab2=%p, tp2=%p, *tp2=%p\n", tab2, tp2, *tp2);

return 0;
}


No i juz dziala inaczej.

J.

J.F.
Guest

Thu May 06, 2004 9:41 am   



On Wed, 5 May 2004 22:08:51 +0200, Piotr Wyderski wrote:
Quote:
for (unsigned char f=1;f<64;f++)

Poza tym postinkrementacji nalezy uzywac tylko gdy
naprawde trzeba; w przeciwnym przypadku nalezy
uzyc preinkrementacji: ++f. W tym przypadku nie
ma to znaczenia, ale jesli zaczniesz programowac w
C++, to zobaczysz roznice, gdy sobie przeciazysz ++.

Nie bardzo rozumiem ?

Quote:
int g;
g=(&polish_chars);

No chyba zartujesz. Smile [...]

PS. Cos wspominales o przejsciu na uprawe marchewki. Wink))

ROTFL Smile
Ale rada dobra - jak sie nie chce czytac podrecznika, to trzeba sie
czym innym zajac :-)

J.

J.F.
Guest

Thu May 06, 2004 9:41 am   



On Wed, 5 May 2004 22:08:54 +0200, Piotr Wyderski wrote:
Quote:
Milosz Skowyra wrote:
Juz sam wiem, olalem warninga kompilatora i zapomnialem o zrzutowaniu
wskaznika na integera ;-)

Wcale nie, to Ty nie przeczytales tego warninga i nie zamieniles
integera na char*. Przykro mi, dopisujac "brakujace" rzutowanie
Ty nie naprawiles tego programu, Ty zgwalciles kompilator. :-

Nic na sile ... wszystko mlotkiem :-)

J.

Jurek Szczesiul
Guest

Thu May 06, 2004 10:05 am   



Thu, 06 May 2004 11:53:20 +0200, na pl.misc.elektronika, Milosz Skowyra
napisał(a):


Quote:
Jeszcze ostatnia niejasnosc...
char x[20],y[20],a;
char *xptr;
xptr=&x; //######
a=*xptr; //w a laduje element x[0]

xptr=&x+1; //######
a=*xptr; //w a laduje element y[0]

xptr=x;
a=*xptr; //w a laduje element x[0]

xptr=x+1;
a=*xptr; //w a laduje element x[1]

juz mysle dobrze czy nadal gdzies blad w logice ??

BTW - czy masz zestawione jakies srodowisko symulacyjne ?
Do takich roznych niuansow jest jak znalazl. Pod Win swietnie
sie sprawdza AvrStudio 4.08

Quote:
I jeszcze jedno. Kompilacja tego powyzej daje w liniach oznaczonych
##### warninga
"main.c:16: warning: assignment from incompatible pointer type". Mam
racje ze chodzi o to ze 2 bajtowy pointer nie miesci sie w char-ze ??

Raczej nie - w avr-gcc wskaznik jest zawsze 16-bitowy ( czyli rozmiar int

). Wiec deklaracja char *xptr; tworzy zmienna dwubajtowa xptr. Natomiast
kompilator kontroluje 'target' wskaznika - jesli chcesz tam wpisac jakas
dowolna liczbe to ostrzega, ze mu sie nie zgadza. Wystarczy poinformowac
xptr=(char*)(&x+1); zeby zgasic warninga.


Pozdrowienia
Jurek Szczesiul

J.F.
Guest

Thu May 06, 2004 11:59 am   



On Thu, 06 May 2004 11:53:20 +0200, Milosz Skowyra wrote:
Quote:
Jeszcze ostatnia niejasnosc...
char x[20],y[20],a;
char *xptr;
xptr=&x; //######
a=*xptr; //w a laduje element x[0]

xptr=&x+1; //######
a=*xptr; //w a laduje element y[0]

Oj, w a laduje x[20]. A czy to jest y[0] to juz tylko konkretny
kompilator wie. Generalnie nie musi.

Quote:
xptr=x+1;
a=*xptr; //w a laduje element x[1]

juz mysle dobrze czy nadal gdzies blad w logice ??

Prawidlowo.

Quote:
I jeszcze jedno. Kompilacja tego powyzej daje w liniach oznaczonych
##### warninga
"main.c:16: warning: assignment from incompatible pointer type". Mam
racje ze chodzi o to ze 2 bajtowy pointer nie miesci sie w char-ze ??

Nie - chodzi o to ze zmieniasz typ wskaznika - tzn typ obiektu
wskazywanego.
A potem bedziesz narzekal ze xptr+1 to nie jest rowne &x+1 ..

Quote:
A swoja droga - o ile kompilator pozwala zdefiniowac taka tablice
w obszarze pgm, to imho powinien poprawnie komplilowac po prostu
polish_chars[f] - albo cos o tym pisze w faq, albo trzeba serwis
powiadomic..

Jak dziala polish_chars[f] to juz podalem Wink

Ale w koncu nie zrozumialem - przekombinowales, czy kompilator
zle dziala ?

J.

Milosz Skowyra
Guest

Thu May 06, 2004 12:04 pm   



"J.F." wrote:

Quote:
Wcale nie, to Ty nie przeczytales tego warninga i nie zamieniles
integera na char*. Przykro mi, dopisujac "brakujace" rzutowanie
Ty nie naprawiles tego programu, Ty zgwalciles kompilator. :-
Nic na sile ... wszystko mlotkiem Smile

Nie takie rzeczy my ze Zbysiem po trzech flaszkach Wink))

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Milosz Skowyra
Guest

Thu May 06, 2004 12:06 pm   



Jurek Szczesiul wrote:

Quote:
BTW - czy masz zestawione jakies srodowisko symulacyjne ?
Do takich roznych niuansow jest jak znalazl. Pod Win swietnie
sie sprawdza AvrStudio 4.08

Mam, robie coff-a i do AvrStudio. Ale czasem to tez nie daje pelnego
obrazka... zwlaszcza jak wiedzy brakuje ;-(

Quote:
I jeszcze jedno. Kompilacja tego powyzej daje w liniach oznaczonych
##### warninga
"main.c:16: warning: assignment from incompatible pointer type". Mam
racje ze chodzi o to ze 2 bajtowy pointer nie miesci sie w char-ze ??
Raczej nie - w avr-gcc wskaznik jest zawsze 16-bitowy ( czyli rozmiar int
). Wiec deklaracja char *xptr; tworzy zmienna dwubajtowa xptr. Natomiast
kompilator kontroluje 'target' wskaznika - jesli chcesz tam wpisac jakas
dowolna liczbe to ostrzega, ze mu sie nie zgadza. Wystarczy poinformowac
xptr=(char*)(&x+1); zeby zgasic warninga.

Jasne. Dzieki.

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Piotr Wyderski
Guest

Thu May 06, 2004 12:23 pm   



J.F. wrote:

Quote:
Nie bardzo rozumiem ?

Roznica jest w definicji wartosci zwracanej przez operator.
W operatorze prefiksowym jest prosto, bo najpierw wykonuje
sie operacje, a dopiero pozniej zwraca zmodyfikowany obiekt.
W przypadku operatora postfiksowego trzeba zwrocic
obiekt opisujacy stan _przed_ wykonaniem operacji, co
pociaga za soba koniecznosc skonstruowania obiektu
tymczasowego. Jesli obiekt jest typu wbudowanego, to
w zasadzie nie ma roznicy, bo kompilator wyrzuci niepotrzebny
obiekt w fazie optymalizacji. Jesli jednak napiszesz wlasny
obiekt implementujacy oba operatory ++, to kompilator nie
bedzie juz mogl tego dokonac. Dlatego warto wyrabiac
sobie nawyk uzywania "tanszych" wersji operatorow, gdy
mozna sobie na to pozwolic. Operator prefiksowy jest tanszy,
bo zazwyczaj zwraca referencje do obiektu, a nie obiekt.

Pozdrawiam
Piotr Wyderski

Milosz Skowyra
Guest

Thu May 06, 2004 12:51 pm   



"J.F." wrote:

Quote:
char x[20],y[20],a;
char *xptr;
xptr=&x; //######
a=*xptr; //w a laduje element x[0]

xptr=&x+1; //######
a=*xptr; //w a laduje element y[0]

Oj, w a laduje x[20]. A czy to jest y[0] to juz tylko konkretny
kompilator wie. Generalnie nie musi.

Zakladajac ze kompilator ulozy w pamieci tablice x i y po sobie (pewnie
nie ma co takiej ewentualnosci zakladac, bo optymalizacja moze
pomieszac, ale jesli chodzi o elementy struktury to chyba mozna cos
takiego zalozyc, czy nie ??) Ale generalnie chodzilo mi o to czy wskaze
nastepny bajt po koncy tablicy x.

Quote:
xptr=x+1;
a=*xptr; //w a laduje element x[1]
juz mysle dobrze czy nadal gdzies blad w logice ??
Prawidlowo.

W koncu... jakas pomrocznosc mnie dopadla.

Quote:
I jeszcze jedno. Kompilacja tego powyzej daje w liniach oznaczonych
##### warninga
"main.c:16: warning: assignment from incompatible pointer type". Mam
racje ze chodzi o to ze 2 bajtowy pointer nie miesci sie w char-ze ??
Nie - chodzi o to ze zmieniasz typ wskaznika - tzn typ obiektu
wskazywanego.
A potem bedziesz narzekal ze xptr+1 to nie jest rowne &x+1 ..

No dobrze, ale ja zrobie jak proponuje Jurek tzn. xptr=(char*) to znow
zgwalce kompilator ??

Quote:
Jak dziala polish_chars[f] to juz podalem Wink
Ale w koncu nie zrozumialem - przekombinowales, czy kompilator
zle dziala ?

Tak dziala i dziala poprawnie konstrukcja:
lcd_port=pgm_read_byte(polish_chars+f);

Diobra.
MOV R31,R29 //adres tablicy w R28-R29
MOV R30,R28
LPM
MOV R24,R0
OUT 0x18,R24
[...] // tu mruganie pinami do wyswietlacza.
SUBI R17,0xFF
ADIW R28,0x01
CPI R17,0x40
BRCS +0x5D

Tak w ogole to dziwi mnie ze bezposrednio nie inkrementuje Z, chociaz Z
nie jest uzywany przez nic innego. Ale moze taka polityka ;-)

To nie dziala (znaczy sie czyta smieci).
lcd_port=pgm_read_byte(polish_chars[f]);

MOV R31,R15 ;r14-r15 adres
MOV R30,R14
LD R24,Z+ ;tego nie kumkam
MOV R14,R30
MOV R15,R31
MOV R30,R24 ;i tego tez
CLR R31
LPM
MOV R24,R0
[...] //tu tez mrugranie liniami LCD
SUBI R28,0xFF
CPI R28,0x40
BRCS +0x59

Wyglada jakby z pamieci programu pobieral 1 bajtowy wskaznik do danej we
flashu. Hmmm dlaczego nie wiem.
Chociaz cos mi zaczelo chodzic po glowie.

[chwila kombinacji............] W faqu jest przyklad:

const char foo[] PROGMEM = "Foo";
const char bar[] PROGMEM = "Bar";

PGM_P array[2] PROGMEM = {
foo,
bar
};

int main (void)
{
char buf[32];
strcpy_P (buf, array[1]);
return 0;
}

Na jego podstawie wyklepalem:

const unsigned char polish_chars[] PROGMEM ={
0x0C,0x04,0x06,0x0C,0x04,0x04,0x0E,0x00, //0 - l
0x00,0x00,0x0E,0x11,0x1F,0x10,0x0E,0x02, //1 = e
0x00,0x02,0x16,0x19,0x11,0x11,0x11,0x00, //2 = n
0x00,0x04,0x1F,0x02,0x04,0x08,0x1F,0x00, //3 = z
0x02,0x04,0x0E,0x011,0x11,0x11,0x0E,0x00, //4 = o
0x00,0x04,0x0E,0x10,0x10,0x11,0x0E,0x00}; //5 = c

PGM_P pol_znak[] ={polish_chars};

Odwolujac sie za pomoca: lcd_port=pgm_read_byte(pol_znak[f]);
dostaje nie dzialajacy kod Wink
MOV R30,R28
CLR R31
LSL R30
ROL R31
SUBI R30,0xA0
SBCI R31,0xFF
LD R0,Z+
LDD R31,Z+0
MOV R30,R0
LDD R24,Z+0
MOV R30,R24
CLR R31
LPM
MOV R24,R0
[...] //mruganie liniami LCD

natomiast dziala
lcd_port=pol_znak[f];
tyle ze kopiuje stringa do RAM.


--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Jurek Szczesiul
Guest

Thu May 06, 2004 1:02 pm   



Thu, 06 May 2004 15:51:19 +0200, na pl.misc.elektronika, Milosz Skowyra
napisał(a):


Quote:
Tak dziala i dziala poprawnie konstrukcja:
lcd_port=pgm_read_byte(polish_chars+f);

polish_chars jest de facto adresem tablicy w ROM,
polish_chars + f = adres f-tego elementu - i OK


Quote:
To nie dziala (znaczy sie czyta smieci).
lcd_port=pgm_read_byte(polish_chars[f]);

A polish_chars[f] juz nie jest adresem tylko wartoscia
f-tego elementu - wiec smieci czyli tez OK Smile
Napisz lcd_port=pgm_read_byte(&polish_chars[f]);

--
Pozdrowienia
Jurek Szczesiul

Milosz Skowyra
Guest

Thu May 06, 2004 1:50 pm   



Jurek Szczesiul wrote:

Quote:
To nie dziala (znaczy sie czyta smieci).
lcd_port=pgm_read_byte(polish_chars[f]);
A polish_chars[f] juz nie jest adresem tylko wartoscia
f-tego elementu - wiec smieci czyli tez OK Smile
Napisz lcd_port=pgm_read_byte(&polish_chars[f]);

Jasne... tepota straszna ze mnie ;-(((

--
Regards. Przy odpowiedzi usun "." przed "net" z adresu!!!
|-----------------------------------------------------|
| Milosz Skowyra GSM Mobile +48 600 95 35 72 |
| miloszek@fido.net.org.pl 2:484/2.47 on fidonet |
|-----------------------------------------------------|

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Dziwne odczyty i zachowanie kompilatora AVRGCC przy pracy z progmem w C?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map