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


von Peter P. (micropirate)


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!
1
int main (void)
2
{
3
  BYTE channel=3;
4
  WORD data=0;
5
  BYTE temp=0;
6
  BYTE buttons;
7
  //Initialize all Ports
8
  IOInit();
9
  InitSwitchSampling();
10
  InitADC();
11
  InitDisplay();
12
  while(1)
13
  {    
14
    if(!Beat)
15
      continue;
16
    //process pressed buttons
17
    buttons = ProcessButtons();
18
    if(buttons!=0)
19
    {
20
      //display String by placing it to Buffer
21
      if(buttons==BUTTON_TOPRIGHT_SHORT)
22
      {
23
        //ADC Value Channel 0
24
        channel=0;
25
        data= GetChannelAverage(channel);
26
        DisplayStringFlash(adcsamplevalue,channel,data);
27
      }
28
      if(buttons == BUTTON_BOTTOMRIGHT_SHORT)
29
      {
30
        //ADC Value Channel 1
31
        channel=1;
32
        data= GetChannelAverage(channel);
33
        DisplayStringFlash(adcsamplevalue,channel,data);
34
      }
35
    }
36
    data =GetChannelAverage(channel);
37
    temp=Calculate(data);
38
    DisplayStringFlash(adcsamplevalue,channel,data); //<-- Das ist die Funktion die nach optimierung einfach weg ist
39
    Beat=0; //Interrupt driven enabling of processing all 100ms
40
  }
41
42
}

was dann im AVRStudio Dissassembly so ausssieht
1
104:          if(!Beat)
2
+0000005C:   9180010E    LDS     R24,0x010E       Load direct from data space
3
+0000005E:   2388        TST     R24              Test for Zero or Minus
4
+0000005F:   F3E1        BREQ    PC-0x03          Branch if equal
5
107:          buttons = ProcessButtons();
6
+00000060:   D37B        RCALL   PC+0x037C        Relative call subroutine
7
+00000061:   8389        STD     Y+1,R24          Store indirect with displacement
8
108:          if(buttons!=0)
9
+00000062:   8189        LDD     R24,Y+1          Load indirect with displacement
10
+00000063:   2388        TST     R24              Test for Zero or Minus
11
+00000064:   F169        BREQ    PC+0x2E          Branch if equal
12
111:            if(buttons==BUTTON_TOPRIGHT_SHORT)
13
+00000065:   8189        LDD     R24,Y+1          Load indirect with displacement
14
+00000066:   3081        CPI     R24,0x01         Compare with immediate
15
+00000067:   F499        BRNE    PC+0x14          Branch if not equal
16
114:              channel=0;
17
+00000068:   821A        STD     Y+2,R1           Store indirect with displacement
18
115:              data= GetChannelAverage(channel);
19
+00000069:   818A        LDD     R24,Y+2          Load indirect with displacement
20
+0000006A:   D419        RCALL   PC+0x041A        Relative call subroutine
21
116:              DisplayStringFlash(adcsamplevalue,channel,data);
22
+0000006B:   812A        LDD     R18,Y+2          Load indirect with displacement
23
+0000006C:   939F        PUSH    R25              Push register on stack
24
+0000006D:   938F        PUSH    R24              Push register on stack
25
+0000006E:   2733        CLR     R19              Clear Register
26
+0000006F:   933F        PUSH    R19              Push register on stack
27
+00000070:   932F        PUSH    R18              Push register on stack
28
+00000071:   E286        LDI     R24,0x26         Load immediate
29
+00000072:   E090        LDI     R25,0x00         Load immediate
30
+00000073:   939F        PUSH    R25              Push register on stack
31
+00000074:   938F        PUSH    R24              Push register on stack
32
+00000075:   D1B6        RCALL   PC+0x01B7        Relative call subroutine
33
+00000076:   B78D        IN      R24,0x3D         In from I/O location
34
+00000077:   B79E        IN      R25,0x3E         In from I/O location
35
+00000078:   9606        ADIW    R24,0x06         Add immediate to word
36
+00000079:   BF9E        OUT     0x3E,R25         Out to I/O location
37
+0000007A:   BF8D        OUT     0x3D,R24         Out to I/O location
38
118:            if(buttons == BUTTON_BOTTOMRIGHT_SHORT)
39
+0000007B:   8189        LDD     R24,Y+1          Load indirect with displacement
40
+0000007C:   3082        CPI     R24,0x02         Compare with immediate
41
+0000007D:   F4A1        BRNE    PC+0x15          Branch if not equal
42
121:              channel=1;
43
+0000007E:   E081        LDI     R24,0x01         Load immediate
44
+0000007F:   838A        STD     Y+2,R24          Store indirect with displacement
45
122:              data= GetChannelAverage(channel);
46
+00000080:   818A        LDD     R24,Y+2          Load indirect with displacement
47
+00000081:   D402        RCALL   PC+0x0403        Relative call subroutine
48
123:              DisplayStringFlash(adcsamplevalue,channel,data);
49
+00000082:   812A        LDD     R18,Y+2          Load indirect with displacement
50
+00000083:   939F        PUSH    R25              Push register on stack
51
+00000084:   938F        PUSH    R24              Push register on stack
52
+00000085:   2733        CLR     R19              Clear Register
53
+00000086:   933F        PUSH    R19              Push register on stack
54
+00000087:   932F        PUSH    R18              Push register on stack
55
+00000088:   E286        LDI     R24,0x26         Load immediate
56
+00000089:   E090        LDI     R25,0x00         Load immediate
57
+0000008A:   939F        PUSH    R25              Push register on stack
58
+0000008B:   938F        PUSH    R24              Push register on stack
59
+0000008C:   D19F        RCALL   PC+0x01A0        Relative call subroutine
60
+0000008D:   B78D        IN      R24,0x3D         In from I/O location
61
+0000008E:   B79E        IN      R25,0x3E         In from I/O location
62
+0000008F:   9606        ADIW    R24,0x06         Add immediate to word
63
+00000090:   BF9E        OUT     0x3E,R25         Out to I/O location
64
+00000091:   BF8D        OUT     0x3D,R24         Out to I/O location
65
126:          data =GetChannelAverage(channel);
66
+00000092:   818A        LDD     R24,Y+2          Load indirect with displacement
67
+00000093:   D3F0        RCALL   PC+0x03F1        Relative call subroutine
68
127:          temp=Calculate(data);
69
+00000094:   D414        RCALL   PC+0x0415        Relative call subroutine
70
?!?!?!?!?!?! Wo ist meine Funktion Ahhhhh
71
129:          Beat=0;
72
+00000095:   9210010E    STS     0x010E,R1        Store direct to data space
73
+00000097:   CFC4        RJMP    PC-0x003B        Relative jump

von Andreas K. (a-k)


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.

von Peter P. (micropirate)


Angehängte Dateien:

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...

von Andreas K. (a-k)


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.

von Peter P. (micropirate)


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

von Andreas K. (a-k)


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.

von Andreas K. (a-k)


Lesenswert?

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

von Peter P. (micropirate)


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
1
DisplayStringFlash(adcsamplevalue,channel,data);
2
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

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


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:
1
        .text
2
.global main
3
        .type   main, @function
4
main:
5
/* prologue: frame size=0 */
6
        ldi r28,lo8(__stack - 0)
7
        ldi r29,hi8(__stack - 0)
8
        out __SP_H__,r29
9
        out __SP_L__,r28
10
/* prologue end (size=4) */
11
        rcall IOInit
12
        rcall InitSwitchSampling
13
        rcall InitADC
14
        rcall InitDisplay
15
        ldi r24,lo8(3)
16
        mov r15,r24
17
        ldi r28,lo8(adcsamplevalue)
18
        ldi r29,hi8(adcsamplevalue)
19
.L14:
20
        lds r24,Beat
21
        tst r24
22
        breq .L14
23
        rcall ProcessButtons
24
        tst r24
25
        breq .L4
26
        cpi r24,lo8(1)
27
        brne .L6
28
        ldi r24,lo8(0)
29
        rcall GetChannelAverage
30
        push r25
31
        push r24
32
        push __zero_reg__
33
        push __zero_reg__
34
        push r29
35
        push r28
36
        rcall DisplayStringFlash
37
        clr r15
38
        rjmp .L13
39
.L6:
40
        cpi r24,lo8(2)
41
        brne .L4
42
        ldi r24,lo8(1)
43
        rcall GetChannelAverage
44
        push r25
45
        push r24
46
        ldi r24,lo8(1)
47
        ldi r25,hi8(1)
48
        push r25
49
        push r24
50
        push r29
51
        push r28
52
        rcall DisplayStringFlash
53
        clr r15
54
        inc r15
55
.L13:
56
        in r24,__SP_L__
57
        in r25,__SP_H__
58
        adiw r24,6
59
        out __SP_H__,r25
60
        out __SP_L__,r24
61
.L4:
62
        mov r24,r15
63
        rcall GetChannelAverage
64
        movw r16,r24
65
        rcall ConvertToDegree
66
        push r17
67
        push r16
68
        mov r24,r15
69
        clr r25
70
        push r25
71
        push r24
72
        push r29
73
        push r28
74
        rcall DisplayStringFlash
75
        sts Beat,__zero_reg__
76
        in r24,__SP_L__
77
        in r25,__SP_H__
78
        adiw r24,6
79
        out __SP_H__,r25
80
        out __SP_L__,r24
81
        rjmp .L14
82
/* epilogue: frame size=0 */
83
/* epilogue: noreturn */
84
/* epilogue end (size=0) */
85
/* function main size 73 (69) */

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

von Dirk D. (dirkd)


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.

von Peter P. (micropirate)


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.
1
typedef struct _displaybuffer
2
{
3
  volatile BYTE bufferreadlock : 1;    //Buffer is locked in SegmentScroll -> Displayfunction
4
  volatile BYTE bufferwritelock: 1;    //Buffer is locked in SegmentScrollStringFlash ->Write to Memoryfunction
5
  char *buffer ;          //Pointer to SRAM Location
6
  BYTE startindex;        //Where to start on String
7
  BYTE scroll    : 5;      //0 scrolls infinite
8
  BYTE done    : 1;      //if scrolling finished bit is set
9
  BYTE direction  : 2;      //LEFT, RIGHT, NONE
10
} 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

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


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.

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.