mikrocontroller.net

Forum: Compiler & IDEs WINAVR GCC Entfernt bei Optimierung einfach Funktionen


Autor: Peter Pan (micropirate)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Habe leider keinerlei hinweise auf derartiges gefunden...

Wer weiss warum die markierte funktion bei allen Optimierungs Optionen 
(ausser 0) einfach weg ist?
Wenn ja dann bitte eine möglichkeit wie ich es erfolgreich verhindern 
kann!!

danke!
int main (void)
{
  BYTE channel=3;
  WORD data=0;
  BYTE temp=0;
  BYTE buttons;
  //Initialize all Ports
  IOInit();
  InitSwitchSampling();
  InitADC();
  InitDisplay();
  while(1)
  {    
    if(!Beat)
      continue;
    //process pressed buttons
    buttons = ProcessButtons();
    if(buttons!=0)
    {
      //display String by placing it to Buffer
      if(buttons==BUTTON_TOPRIGHT_SHORT)
      {
        //ADC Value Channel 0
        channel=0;
        data= GetChannelAverage(channel);
        DisplayStringFlash(adcsamplevalue,channel,data);
      }
      if(buttons == BUTTON_BOTTOMRIGHT_SHORT)
      {
        //ADC Value Channel 1
        channel=1;
        data= GetChannelAverage(channel);
        DisplayStringFlash(adcsamplevalue,channel,data);
      }
    }
    data =GetChannelAverage(channel);
    temp=Calculate(data);
    DisplayStringFlash(adcsamplevalue,channel,data); //<-- Das ist die Funktion die nach optimierung einfach weg ist
    Beat=0; //Interrupt driven enabling of processing all 100ms
  }

}

was dann im AVRStudio Dissassembly so ausssieht
104:          if(!Beat)
+0000005C:   9180010E    LDS     R24,0x010E       Load direct from data space
+0000005E:   2388        TST     R24              Test for Zero or Minus
+0000005F:   F3E1        BREQ    PC-0x03          Branch if equal
107:          buttons = ProcessButtons();
+00000060:   D37B        RCALL   PC+0x037C        Relative call subroutine
+00000061:   8389        STD     Y+1,R24          Store indirect with displacement
108:          if(buttons!=0)
+00000062:   8189        LDD     R24,Y+1          Load indirect with displacement
+00000063:   2388        TST     R24              Test for Zero or Minus
+00000064:   F169        BREQ    PC+0x2E          Branch if equal
111:            if(buttons==BUTTON_TOPRIGHT_SHORT)
+00000065:   8189        LDD     R24,Y+1          Load indirect with displacement
+00000066:   3081        CPI     R24,0x01         Compare with immediate
+00000067:   F499        BRNE    PC+0x14          Branch if not equal
114:              channel=0;
+00000068:   821A        STD     Y+2,R1           Store indirect with displacement
115:              data= GetChannelAverage(channel);
+00000069:   818A        LDD     R24,Y+2          Load indirect with displacement
+0000006A:   D419        RCALL   PC+0x041A        Relative call subroutine
116:              DisplayStringFlash(adcsamplevalue,channel,data);
+0000006B:   812A        LDD     R18,Y+2          Load indirect with displacement
+0000006C:   939F        PUSH    R25              Push register on stack
+0000006D:   938F        PUSH    R24              Push register on stack
+0000006E:   2733        CLR     R19              Clear Register
+0000006F:   933F        PUSH    R19              Push register on stack
+00000070:   932F        PUSH    R18              Push register on stack
+00000071:   E286        LDI     R24,0x26         Load immediate
+00000072:   E090        LDI     R25,0x00         Load immediate
+00000073:   939F        PUSH    R25              Push register on stack
+00000074:   938F        PUSH    R24              Push register on stack
+00000075:   D1B6        RCALL   PC+0x01B7        Relative call subroutine
+00000076:   B78D        IN      R24,0x3D         In from I/O location
+00000077:   B79E        IN      R25,0x3E         In from I/O location
+00000078:   9606        ADIW    R24,0x06         Add immediate to word
+00000079:   BF9E        OUT     0x3E,R25         Out to I/O location
+0000007A:   BF8D        OUT     0x3D,R24         Out to I/O location
118:            if(buttons == BUTTON_BOTTOMRIGHT_SHORT)
+0000007B:   8189        LDD     R24,Y+1          Load indirect with displacement
+0000007C:   3082        CPI     R24,0x02         Compare with immediate
+0000007D:   F4A1        BRNE    PC+0x15          Branch if not equal
121:              channel=1;
+0000007E:   E081        LDI     R24,0x01         Load immediate
+0000007F:   838A        STD     Y+2,R24          Store indirect with displacement
122:              data= GetChannelAverage(channel);
+00000080:   818A        LDD     R24,Y+2          Load indirect with displacement
+00000081:   D402        RCALL   PC+0x0403        Relative call subroutine
123:              DisplayStringFlash(adcsamplevalue,channel,data);
+00000082:   812A        LDD     R18,Y+2          Load indirect with displacement
+00000083:   939F        PUSH    R25              Push register on stack
+00000084:   938F        PUSH    R24              Push register on stack
+00000085:   2733        CLR     R19              Clear Register
+00000086:   933F        PUSH    R19              Push register on stack
+00000087:   932F        PUSH    R18              Push register on stack
+00000088:   E286        LDI     R24,0x26         Load immediate
+00000089:   E090        LDI     R25,0x00         Load immediate
+0000008A:   939F        PUSH    R25              Push register on stack
+0000008B:   938F        PUSH    R24              Push register on stack
+0000008C:   D19F        RCALL   PC+0x01A0        Relative call subroutine
+0000008D:   B78D        IN      R24,0x3D         In from I/O location
+0000008E:   B79E        IN      R25,0x3E         In from I/O location
+0000008F:   9606        ADIW    R24,0x06         Add immediate to word
+00000090:   BF9E        OUT     0x3E,R25         Out to I/O location
+00000091:   BF8D        OUT     0x3D,R24         Out to I/O location
126:          data =GetChannelAverage(channel);
+00000092:   818A        LDD     R24,Y+2          Load indirect with displacement
+00000093:   D3F0        RCALL   PC+0x03F1        Relative call subroutine
127:          temp=Calculate(data);
+00000094:   D414        RCALL   PC+0x0415        Relative call subroutine
?!?!?!?!?!?! Wo ist meine Funktion Ahhhhh
129:          Beat=0;
+00000095:   9210010E    STS     0x010E,R1        Store direct to data space
+00000097:   CFC4        RJMP    PC-0x003B        Relative jump

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Reduziere das mal auf ein einzelnes Quellfile, das nicht nur für dich 
kompilierbar ist. So dass also alles bekannt ist, Compiler-Optionen 
inklusive.

Und mit möglichst wenig drumherum. Also alles nacheinander rauswerfen, 
nur dann drinlassen wenn sonst das Problem nicht mehr auftritt.

Autor: Peter Pan (micropirate)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ist kein geheim projekt, deshalb hab ich alle files so belassen.
Den Code hab ich nicht zusammen gestrippt, sondern das Makefile 
mitgegeben.
compilierbar sollte es dann sein.

Danke fürs Helfen...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Pan wrote:

> Ist kein geheim projekt, deshalb hab ich alle files so belassen.

Das heisst du willst, dass andere Leute für dich diese Arbeit machen.

Guten Tag noch.

Autor: Peter Pan (micropirate)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmm,
welche Arbeit?!

** das gilt nur für Andreas Kaiser **

ich versteh nicht warum du das so emotional siehst, von wegen arbeit 
abgeben, die arbeit wartet noch, das sind nur testrümpfe und treiber die 
diese applikation zusammenhalten und die testschleife is bei gott keine 
app.

anstatt sich zu freuen, dass es unkompliziert und effizient über die 
bühne geht, denn fragen welches setting welche files warum wieso, dem 
ist am einfachsten entgegengewirkt...mit den settings wies nicht 
funktioniert oder?!

** ende **

denn damit kann man im AVRStudio auf einen Blick sehen dass es so ist 
wie ichs gepostet habe. aber scheinbar war das ja auch nicht genug.

ich dachte da eher an jemanden der wirklich mit GCC vertraut ist und 
etwas mehr weiss als die manuals hervorbringen und mir diese eine simple 
frage beantworten kann:

!! Warum Strippt/kombiniert der GCC Compiler mit der Option Os, O1, O2, 
O3 mir einfach diese funktion, bzw. wie kann ich ihm klarmachen dass es 
einen Codeblock gibt der nicht zu optimieren ist !!

Danke an eventuelle Hilfestellungen die nicht ausarten in ein heckmeck

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Langfassung:

Eine einfache Antwort habe ich nicht gefunden. Da die aufgerufene 
Funktion mehrfach darin vorkommt, ist unwahrscheinlich, dass er sie aus 
irgendwelchen im Originalposting nicht erkennbaren Ursachen 
wegoptimieren sollte (leere Funktion inlined, oder sowas in der Art).

Folglich ist das erste, was ich einem solchen Fall machen würde: Alles 
überflüssige aus dem Testcode rauskürzen, so dass nur noch das 
Essentielle übrig bleibt. Idealerweise ohne dass irgendwelche 
Include-Files nötig sind.

Entweder erkennt man bei dieser Prozedur schon, wo der Hund begraben 
liegt.

Oder es bleibt etwas übrig, dass tatsächlich nach Compilerfehler 
aussieht. Dann sollte man das sowieso machen, denn sonst ersäuft 
derjenige, der den erforschen will, im Unwichtigen.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja: Beat sollte "volatile" sein. Gibt hier irgendwo einen Artikel 
dazu, aber weiss der Geier wie der heisst.

Autor: Peter Pan (micropirate)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ja an register und volatile hab ich nach dem posting eh gedacht und 
mitlerweile hab ich volatile an allem getestet was dafür in frage käme.
eine weiter kleine entdeckung viellicht ist es ein hinweis:

alle variablen die ich übergebe scheinen starr zu sein. d.h.
mache ich aus
DisplayStringFlash(adcsamplevalue,channel,data);
DisplayStringFlash(adcsamplevalue,data++,data++);

wird mir nur der wert gezeigt, mit der die variable data anfangs 
initialisiert wurde. und der ändert sich keinesfalls.

Danke nochmal ich werd noch etwas experimentieren

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da wird nichts wegoptimiert.  Die Schleife wird nicht einmal
nennenswert umsortiert.

Manchmal ist es sinnvoller, sich statt des Disassemblerlistings den
generierten Assemblercode des Compilers anzusehen:
        .text
.global main
        .type   main, @function
main:
/* prologue: frame size=0 */
        ldi r28,lo8(__stack - 0)
        ldi r29,hi8(__stack - 0)
        out __SP_H__,r29
        out __SP_L__,r28
/* prologue end (size=4) */
        rcall IOInit
        rcall InitSwitchSampling
        rcall InitADC
        rcall InitDisplay
        ldi r24,lo8(3)
        mov r15,r24
        ldi r28,lo8(adcsamplevalue)
        ldi r29,hi8(adcsamplevalue)
.L14:
        lds r24,Beat
        tst r24
        breq .L14
        rcall ProcessButtons
        tst r24
        breq .L4
        cpi r24,lo8(1)
        brne .L6
        ldi r24,lo8(0)
        rcall GetChannelAverage
        push r25
        push r24
        push __zero_reg__
        push __zero_reg__
        push r29
        push r28
        rcall DisplayStringFlash
        clr r15
        rjmp .L13
.L6:
        cpi r24,lo8(2)
        brne .L4
        ldi r24,lo8(1)
        rcall GetChannelAverage
        push r25
        push r24
        ldi r24,lo8(1)
        ldi r25,hi8(1)
        push r25
        push r24
        push r29
        push r28
        rcall DisplayStringFlash
        clr r15
        inc r15
.L13:
        in r24,__SP_L__
        in r25,__SP_H__
        adiw r24,6
        out __SP_H__,r25
        out __SP_L__,r24
.L4:
        mov r24,r15
        rcall GetChannelAverage
        movw r16,r24
        rcall ConvertToDegree
        push r17
        push r16
        mov r24,r15
        clr r25
        push r25
        push r24
        push r29
        push r28
        rcall DisplayStringFlash
        sts Beat,__zero_reg__
        in r24,__SP_L__
        in r25,__SP_H__
        adiw r24,6
        out __SP_H__,r25
        out __SP_L__,r24
        rjmp .L14
/* epilogue: frame size=0 */
/* epilogue: noreturn */
/* epilogue end (size=0) */
/* function main size 73 (69) */

Deine Warnung mit va_start aus 
Beitrag "GCC Optimierungs problem!"
hast du ja auch immer noch drin...

Autor: Dirk Dörr (dirkd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur so am Rande:

DisplayStringFlash(adcsamplevalue,data++,data++);

Sieht mir gefährlich aus. Ich würde mal sagen, daß der C-Standard nicht 
definiert welche Werte übergeben werden (für data) und das ganze sehr 
Compiler-abhängig ist.

Für data=0

könnte es

DisplayStringFlash(adcsamplevalue,0,0);

DisplayStringFlash(adcsamplevalue,0,1);

DisplayStringFlash(adcsamplevalue,1,1);

oder vielleicht

DisplayStringFlash(adcsamplevalue,1,2);


sein.

Autor: Peter Pan (micropirate)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Danke für euer input..
habe heute viel gelernt...

Wie nehm ich den den beitrag wieder raus?

Falls es jemand interessiert:
Hab den fehler gefunden aufgrund des generierten Assembler listings.
Das problem war der bufferlock in der Display struktur. die im interrupt 
gesetzt wurde um nicht gleichzeitig zu reinzuschreiben und 
rauszukopieren.

tja und alles was im interrupt gesetzt wird muss scheinbar volatile 
sein.
typedef struct _displaybuffer
{
  volatile BYTE bufferreadlock : 1;    //Buffer is locked in SegmentScroll -> Displayfunction
  volatile BYTE bufferwritelock: 1;    //Buffer is locked in SegmentScrollStringFlash ->Write to Memoryfunction
  char *buffer ;          //Pointer to SRAM Location
  BYTE startindex;        //Where to start on String
  BYTE scroll    : 5;      //0 scrolls infinite
  BYTE done    : 1;      //if scrolling finished bit is set
  BYTE direction  : 2;      //LEFT, RIGHT, NONE
} chardisplaybuffer;

habs noch ein wenig angepasst, aber ohne eure hilfe hätt ich den fehler 
nie gefunden...
tja wieder ein tag vers...chönert.... mit einem bug der norm. kein bug 
ist.

schöne woche leute

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Pan wrote:

> tja und alles was im interrupt gesetzt wird muss scheinbar volatile
> sein.

Nicht alles.  Erstens muss natürlich alles das, was nur innerhalb
der ISR benutzt wird, nicht volatile sein.  Für die Kommunikation
zwischen verschiedenen Code-Threads (also ISR vs. main(), ISR vs.
andere ISR) ist es sehr oft notwendig.  Wenn man die C-Regeln über
all den Kram wie sequence points und mögliche Compiler-Umsortierung
einigermaßen kennt, kann man ggf. noch ein wenig einschränken, wo
volatile wirklich gebraucht wird.

Vorsicht!, volatile ist eine heftige Performance-Bremse.  Wenn man
mehr also nur kurze Operationen mit entsprechenden Variablen
vornimmt, sollte man sie in lokalen Kopien cachen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.