AVR gcc - pytanie



Masz problem? Zapytaj na forum elektroda.pl

Poprzedni Następny
Wiadomość
Spis treści
From: MariuszC <marcukr_at_nospam_op.pl>
Subject: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 10:04:38 +0100


Witam,
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<8) | byValue2;
albo
wValue = (byValue1<<8) + byValue2;

promują byValue1 oraz byValue2 do liczby unsigned short
potem je ORują ze sobą, a przecież wiadomo że byValue1
ma trafić na starszy bajt wValue, a byValue2 na młodszy
i to wszystko.

Są jakieś makra jak np:
HIBYTE(wValue) = byValue1;
LOBYTE(wValue) = byValue2;
dzięki którym kompilator by wpisywał wartość do odpowiedniego
rejestru, albo komórki pamięci? Ja nie znalazłem, albo przegapiłem
(jeśli w ogóle coś takiego istnieje). Może Ktoś z Was zna rozwiązanie.
Po prostu wkurza mnie, że zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.

Mariusz


Poprzedni Następny
Wiadomość
Spis treści
From: Piotr Chmiel <piotr_at_nospam_topaz.zsel.lublin.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 11:11:02 +0100


On Tue, 9 Nov 2004, MariuszC wrote:

Po prostu wkurza mnie, =BFe zawsze brakuje FLASHa, a kompilator
dodatkowo generuje niepotrzebny kod, tymbardziej w takich prostych
przypadkach.

A ile go masz =BFe Ci ci=B1gle brakuje ?
Dostosuj AVR do swoich potrzeb :)


Poprzedni Następny
Wiadomość
Spis treści
From: Andrzej Ekiert <reply_at_nospam_to.invalid>
Subject: Re: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 11:19:13 +0100


MariuszC wrote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
unsigned short wValue;
unsigned char byValue1, byValue2;
wValue = (byValue1<<8) | byValue2;
albo
wValue = (byValue1<<8) + byValue2;


Nie używam co prawda AVRów, ale na taki sam problem pod gcc na procesory
dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w sposób następujący:

/*
* Use when assigning to unsigned 8-bit variable
* (x is a 16 bit variable)
*/
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.

hth,
--
Andrzej Ekiert
Polskie Forum Microchipa
http://www.ekiert.com/microchip

Poprzedni Następny
Wiadomość
Spis treści
From: "Marek Dzwonnik" <mdz_at_nospam_WIADOMO_PO_CO_TO.message.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 12:19:19 +0100


Użytkownik "Andrzej Ekiert" <reply_at_nospam_to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1_at_nospam_polsl.gliwice.pl
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<8) | byValue2;
albo
wValue = (byValue1<<8) + byValue2;

dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:

union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;

value.asWord
value.asByte.b1
value.asByte.b2

--
Marek Dzwonnik, GG: #2061027 - zwykle jako 'niewidoczny'
(Uwaga Gadu-Gadulcowicze: Nie odpowiadam na anonimy.)


Poprzedni Następny
Wiadomość
Spis treści
From: MariuszC <marcukr_at_nospam_op.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 15:47:55 +0100


Marek Dzwonnik wrote:
Użytkownik "Andrzej Ekiert" <reply_at_nospam_to.invalid> napisał w wiadomości
news:cmq5j2$jpv$1_at_nospam_polsl.gliwice.pl

czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.
Np:
wValue = (byValue1<<8) | byValue2;
albo
wValue = (byValue1<<8) + byValue2;


dsPIC Microchipa, oraz pod mcc18 na PIC18 rozwiązałem w
sposób następujący:
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))


A może z wykorzystaniem unii zawierajacej alternatywnie jednego int-a albo
strukture zlozona z dwoch bajtów? To wprawdzie nie jest zbyt legalne, ale
powinno działać:

union {
struct {
unsigned char b1;
unsigned char b2;
} asByte;
unsigned int asWord;
} value;

value.asWord
value.asByte.b1
value.asByte.b2

Też to ćwiczyłem i jest znacznie lepiej, jednak np
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB

Mariusz


Poprzedni Następny
Wiadomość
Spis treści
From: "Mister" <wojpie_at_nospam_wywal_to.poczta.onet.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 16:20:51 +0100


po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB


Tak jest. I to jest denerwujące.

Mister



Poprzedni Następny
Wiadomość
Spis treści
From: "Marek Dzwonnik" <mdz_at_nospam_WIADOMO_PO_CO_TO.message.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 17:32:11 +0100


Użytkownik "Mister" <wojpie_at_nospam_wywal_to.poczta.onet.pl> napisał w
wiadomości news:cmqn9j$dmd$1_at_nospam_atlantis.news.tpi.pl
po przeniesieniu części kodu na 51 trzeba będzie pamiętać
że one chyba (dawno nic w nich nie robiłem) mają
odwrotny zapis MSB,LSB, a nie jak w AVR LSB,MSB

Tak jest. I to jest denerwujące.


W takim razie zależnie od typu procesora zdefiniować:
#define MSB b1
#define LSB b2

lub na odwrót
#define MSB b2
#define LSB b1

i odwoływać się do pól struktury przez MSB i LSB.
value.asByte.MSB
value.asByte.LSB

--
MDz


Poprzedni Następny
Wiadomość
Spis treści
From: J.F. <jfox_nospam_at_nospam_poczta.onet.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 12:49:47 +0100


On Tue, 09 Nov 2004 11:19:13 +0100, Andrzej Ekiert wrote:
czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.

wValue = (byValue1<<8) | byValue2;
albo
wValue = (byValue1<<8) + byValue2;

#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.

Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu :-)

Chyba lepiej to pierwsze i zdac sie na optymalizator.

J.


Poprzedni Następny
Wiadomość
Spis treści
From: Albert Bartoszko <albertb_at_nospam_nt.kegel.com.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 15:16:12 +0100


Użytkownik J.F. napisał:
[...]
#define HIGH_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)+1))
#define LOW_BYTE(x) (*(unsigned char*)((unsigned char*)(&x)))

Paskudne to to jest, wiem.


Paskudne. Bo sie okaze na innym procku [np AVR] zmienna jest w jednym
z [np 32] rejestrow i nie ma adresu :-)

Nie, po użyciu czegoś takiego już nie będzie w rejestrze i będzie miała
adres.


Chyba lepiej to pierwsze i zdac sie na optymalizator.
Jak ktoś jest tak oszczędny to jednak proponowałbym asembler

Albert

Poprzedni Następny
Wiadomość
Spis treści
From: Jurek Szczesiul <jerzy.szczesiul_at_nospam_wycin.ep.com.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 17:37:06 +0100


Tue, 09 Nov 2004 10:04:38 +0100, na pl.misc.elektronika, MariuszC
napisał(a):

czy da się jakoś zapisać kod w C, aby otrzymać liczbę dwubajtową
unsigned short z dwóch liczb unsigned char tak, aby kompilator
wygenerował jak najmniej kodu.

Cześć.

memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17


--
Pozdrowienia
Jurek Szczesiul

Poprzedni Następny
Wiadomość
Spis treści
From: J.F. <jfox_nospam_at_nospam_poczta.onet.pl>
Subject: Re: AVR gcc - pytanie
Date: Tue, 09 Nov 2004 18:13:11 +0100


On Tue, 9 Nov 2004 17:37:06 +0100, Jurek Szczesiul wrote:
memcpy((char*)&word,(char*)&chr2,1);
64: 00 91 62 00 lds r16, 0x0062
68: 00 93 74 00 sts 0x0074, r16
memcpy((char*)&word+1,(char*)&chr1,1);
6c: 10 91 63 00 lds r17, 0x0063
70: 10 93 75 00 sts 0x0075, r17


Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

J.


Poprzedni Następny
Wiadomość
Spis treści
From: "Marcin Stanisz" <mstaniszWYTNIJTO_at_nospam_poczta.onet.pl>
Subject: Re: AVR gcc - pytanie
Date: 9 Nov 2004 19:00:43 +0100


Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

I to jest dopiero optymalizacja! ;-)

Pozdrawiam

Marcin Stanisz



--
Wysłano z serwisu OnetNiusy: http://niusy.onet.pl

Poprzedni Następny
Wiadomość
Spis treści
From: Marek Michalkiewicz <spamtrap_at_nospam_amelek.gda.pl.invalid>
Subject: Re: AVR gcc - pytanie
Date: Tue, 9 Nov 2004 21:45:36 +0100 (CET)


J.F. <jfox_nospam_at_nospam_poczta.onet.pl> wrote:

Eeeee .. czy on ma prawo tak robic ?
powinien wywolac funkcje biblioteczna memcpy.

Ma prawo. GCC (na kazda architekture, niekoniecznie AVR) ma troche
funkcji wbudowanych - zamiast wywolania funkcji moze wygenerowac
kawalek kodu, robiacy to samo tylko bardziej efektywnie. Mozna
uzyc -fno-builtin (lub dla konkretnej funkcji: -fno-builtin-memcpy)
by te optymalizacje wylaczyc.

Wstawienie kawalka kodu ma te przewage nad wywolaniem funkcji, ze
nie "zapomina" sie tylu rejestrow (AVR: r18-r27 i r30-r31), wiec
moze sie oplacac nawet dla funkcji nieco wiekszych niz memcpy().

Marek