Forum: Compiler & IDEs AVR-GCC 16Bit-Lastigkeit nervt


von Peter D. (peda)


Lesenswert?

Warum hängt der AVR-GCC so an 16Bit bei 8Bit Berechnungen?
1
void test()
2
{
3
  if( PINB & (1<<PB0 | 1<<PB1) )
4
  80:   83 b1           in      r24, 0x03       ; 3
5
  82:   90 e0           ldi     r25, 0x00       ; 0
6
  84:   83 70           andi    r24, 0x03       ; 3
7
  86:   90 70           andi    r25, 0x00       ; 0
8
  88:   89 2b           or      r24, r25
9
  8a:   09 f0           breq    .+2             ; 0x8e <test+0xe>
10
    PORTB = 0;
11
  8c:   15 b8           out     0x05, r1        ; 5
12
  8e:   08 95           ret

Statt 6 Byte kostet der Vergleich 12 Byte (= 200%).
Aber nur, wenn der Test auch Bit 0 enthällt.
1
void test2()
2
{
3
  if( PINB & (1<<PB1 | 1<<PB2) )
4
  90:   83 b1           in      r24, 0x03       ; 3
5
  92:   86 70           andi    r24, 0x06       ; 6
6
  94:   09 f0           breq    .+2             ; 0x98 <test2+0x8>
7
    PORTB = 0;
8
  96:   15 b8           out     0x05, r1        ; 5
9
  98:   08 95           ret

Ich benutze WINAVR 2010.


Peter

von Peter II (Gast)


Lesenswert?

was passiert bei:
1
 if( PINB & (1<<PB0) || PINB & (1<<PB1) )
?

von Peter D. (peda)


Lesenswert?

Das ist funktional völlig anderer Code, es müssen 2 Zugriffe 
nacheinander auf PINB gemacht werden. Und dazwischen könnte ein 
Interrupt kommen, d.h. dann sind viele µs Unterschied, statt 
gleichzeitig.

Das PINB ist nur als Beispiel gemeint. Es kann auch ein IO-Register im 
RAM-Space sein (>0x0100).



Peter

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Statt 6 Byte kostet der Vergleich 12 Byte (= 200%).

Kann ich bei mir nachvollziehen.

> Aber nur, wenn der Test auch Bit 0 enthällt.

Stimmt nicht, benutze mal

    if( PINB & (1<<PB0 | 1<<PB2))

Hier wird wieder die kurze Variante vom Compiler gewählt.

> Ich benutze WINAVR 2010.

Ich normalerweise auch, konnte aber das Problem sogar mit 
WinAVR-20090313 nachstellen.

EDIT:
Das Problem scheint nur in der Kombination PB0 und PB1, also (PINB & 
3), aufzutreten. Ich habe keine andere hinbekommen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bei avr-gcc 4.7.0 und 4.7.1 besteht dieses Problem nicht mehr.
Vielleicht solltest Du doch mal auf einen neueren Compiler wechseln ;-)

von Peter D. (peda)


Lesenswert?

Frank M. schrieb:
> Das Problem scheint nur in der Kombination PB0 und PB1, also (PINB &
> 3), aufzutreten. Ich habe keine andere hinbekommen.

Also bei geht alles von Bit 0 aufsteigend, also Maske 3, 7, 15, 31, 63, 
127.
Mit Lücke oder ohne Bit 0 wirds kurz.

Hier mal die Funktion, wo es mir aufgefallen ist:
1
void sleep()
2
{
3
  cli();
4
  if( !(ASSR & (1<<TCN2UB | 1<<OCR2AUB | 1<<OCR2BUB | 1<<TCR2AUB | 1<<TCR2BUB)))
5
  {
6
    sei();
7
    sleep_cpu();
8
    return;
9
  }
10
  sei();
11
}

Frank M. schrieb:
> Vielleicht solltest Du doch mal auf einen neueren Compiler wechseln ;-)

Ist die zu empfehlen:

avr-gcc-4.7.1-rc1-mingw32.zip


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> avr-gcc-4.7.1-rc1-mingw32.zip

Da 4.7.1 bereits released ist, würde ich keinen RC ("release
candidate") mehr nehmen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Ist die zu empfehlen:
>
> avr-gcc-4.7.1-rc1-mingw32.zip

Hier ein Posting von Johann zur Wahl des avr-gcc:

Beitrag "Re: 16Bit aus 2x 8Bit, falsches Ergebnis bei Funktionsrückgabe"

4.7.1 ist also okay (aber nicht unbedingt rc1), 4.7.0 weniger.

von Peter D. (peda)


Lesenswert?

Jörg Wunsch schrieb:
> Peter Dannegger schrieb:
>> avr-gcc-4.7.1-rc1-mingw32.zip
>
> Da 4.7.1 bereits released ist, würde ich keinen RC ("release
> candidate") mehr nehmen.

Diesen Link habe ich in AVR Freaks "avr-gcc 4.7.0 for the brave" 
gefunden:

http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/

Hast Du nen Link ohne RC?

Irgendwie fehlt ja nach WINAVR 2010 ne offizielle Anlaufstelle für neue 
Versionen zum Downloaden.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Hast Du nen Link ohne RC?

Nein, ich bau' mir meine Compiler ohnehin immer selbst. ;-)  's ist
ja keine Raketenwissenschaft, das zu tun.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Peter Dannegger schrieb:
>> avr-gcc-4.7.1-rc1-mingw32.zip
>
> Da 4.7.1 bereits released ist, würde ich keinen RC ("release
> candidate") mehr nehmen.

Wobei diese RC1 Bugfixes anthält, die in der offiziellen 4.7.1 nicht 
enthalten sind  ;-)

Siehe die Patches in ./source

GCC:
 http://gcc.gnu.org/PR53595

Binutils:
 http://sourceware.org/PR13899
 http://sourceware.org/PR14058


Jörg Wunsch schrieb:

> Nein, ich bau' mir meine Compiler ohnehin immer selbst. ;-)
> 's ist ja keine Raketenwissenschaft, das zu tun.

>> "Come on, Rory. It's not rocket science. It's just quantum physics."

von Adib (Gast)


Lesenswert?

irgendwo hatte ich mal gelesen, dass bit operationen im C als int 
behandelt werden.

Das würde das Type-Casting erklären.

Adib.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Adib schrieb:
> dass bit operationen im C als int
> behandelt werden.

Der C-Standard ist ein "als wäre"-Standard: die Operationen müssen
sich so verhalten, als wären sie als "int" behandelt worden.  Wenn
aber das obere Byte zum Ergebnis nichts beiträgt, steht es dem
Compiler sehr wohl frei, nur das niederwertige Byte überhaupt
ausrechnen zu lassen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.