AVR gcc - pytanie

Nov 09, 2004 12 Replies

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


A ile go masz że Ci ciągle brakuje ? Dostosuj AVR do swoich potrzeb :)

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,

U¿ytkownik "Andrzej Ekiert" snipped-for-privacy@to.invalid napisa³ w wiadomo¶ci news:cmq5j2$jpv$ snipped-for-privacy@polsl.gliwice.pl

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

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.

Użytkownik J.F. napisał: [...]

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

Jak ktoś jest tak oszczędny to jednak proponowałbym asembler

Albert

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

Tak jest. I to jest denerwuj±ce.

Mister

U¿ytkownik "Mister" <wojpie@wywal_to.poczta.onet.pl> napisa³ w wiadomo¶ci news:cmqn9j$dmd$ snipped-for-privacy@atlantis.news.tpi.pl

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

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

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

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

J.

I to jest dopiero optymalizacja! ;-)

Pozdrawiam

Marcin Stanisz

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

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required