Hallo zusammen, irgendwie stehe ich auf dem Schlauch - geb gerne zu das mein C eingerostet ist, aber warum der WINAVR-GCC die folgende Zeile nicht ausführt bzw. anscheinend erst gar nicht compiliert - verstehe ich nicht TimerCnt += 32/8; //_TIME_CONST_US_TIMER_CLOCK (32); // Diese Zeile erscheint in keinster Weise im Disassembler-Code. Beim Debuggen hüpft er drüber und die Variable hat den Wert Null. Compiler-Option -Os (keine Optimierung ) ist gewählt. Mache ich daraus ein TimerCnt += 4; dann wird die Zeile ausgeführt.... Kann mir jemand auf die Sprünge helfen was die schief geht? Gruss, Gary
In deinem Code steht TimerCnt += 32.0/8.0; Das ist ein Ausdruck vom Typ "float", schreibt mal (wie oben) TimerCnt += 32/8; /* Integer-Ausdruck */ Vielleicht klappts dann.
Sorry das war der letzte Spielstand, aber es ging in jedem Fall nicht.
Da läuft irgendwas im Compiler schief habe nun ein noch einfachers Beispiel gezimmert... anbei das Disassembly @00000030: main 12: { +00000030: E084 LDI R24,0x04 Load immediate +00000031: E090 LDI R25,0x00 Load immediate +00000032: 019C MOVW R18,R24 Copy register pair 7: while(--i); +00000033: 01C9 MOVW R24,R18 Copy register pair +00000034: 9701 SBIW R24,0x01 Subtract immediate from word +00000035: E024 LDI R18,0x04 Load immediate +00000036: E030 LDI R19,0x00 Load immediate +00000037: F7D1 BRNE PC-0x05 Branch if not equal +00000038: CFFA RJMP PC-0x0005 Relative jump +00000039: 94F8 CLI Global Interrupt Disable +0000003A: CFFF RJMP PC-0x0000 Relative jump
Ist doch alles richtig? die Delay-Methode wird inline in main reinkopiert, die Berechnungen auf Var werden wegoptimiert, weil der berechnete Wert nie verwendet wird.
@ernst Das der Compiler hier optimiert habe ich mir auch schon überlegt, aber deswegen habe ich auch die Option -Os drin gelassen. hier ein erweitertes Beispiel #include <stdio.h> #include <stdint.h> void Delay( void ) { uint16_t i= 0x4;/*1 7FFF;*/ while(--i); } int main(void) { uint8_t Var=0; uint8_t Test; while ( 1 ) { Delay(); // Var = 32/8; Var = Var+1; Test = Var; for (Test = 0; Test<= Var; Test++) { } } } So gehts - nimm die kommentierte Zeile wieder rein - und er macht nichts auser dem Delay.
Dann optimiert dein GCC schlecht. Bei mir kommt raus: Version mit "Var=32/8":
1 | .L10: |
2 | ldi r24,lo8(4) |
3 | ldi r25,hi8(4) |
4 | .L9: |
5 | sbiw r24,1 |
6 | brne .L9 |
7 | rjmp .L10 |
Version ohne:
1 | ldi r18,lo8(0) |
2 | .L4: |
3 | subi r18,lo8(-(1)) |
4 | ldi r24,lo8(0) |
5 | ldi r25,hi8(0) |
6 | .L5: |
7 | adiw r24,1 |
8 | cp r18,r24 |
9 | brsh .L5 |
10 | rjmp .L4 |
Tip:
1 | uint16_t i= 0x4; |
2 | while(--i); |
kann der Compiler optimieren zu:
1 | uint16_t i=0; |
und wenn i nicht weiter verwendet wird, kann er es ganz rausschmeissen. Ähnlich:
1 | for (Test = 0; Test<= Var; Test++) { } |
Wird zu:
1 | Test=Var+1; |
@ernst... danke... habe mir nun die brand-aktuelle Version geladen UND habe gerade festgestellt das -Os ja doch auf Size optimiert. Mit der Option -O0 ist gut, dann macht er alles richtig... sorry für die Mühe, aber manchmal ;) Ich wollte ja nur mein Makro testen ;)) Danke nochmal
Gerhard Brünner wrote: > @ernst... > > danke... habe mir nun die brand-aktuelle Version geladen UND > habe gerade festgestellt das -Os ja doch auf Size optimiert. > Mit der Option -O0 ist gut, dann macht er alles richtig... > Richtig macht er es auch mit -Os, zumindest was das Ergebnis anbelangt. Aber zum ASM-Code anschauen ist -O0 besser geeignet, oder halt auf einzelnen Variablen das Optimieren verbieten, mit "volatile"...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.