Forum: Compiler & IDEs Compiler optimiert Code weg, was er nicht sollte


von Matthias F. (idefix)


Lesenswert?

Hi,

ich habe mir hier eine LCD Routine geschrieben um Sachen auf einem LCD 
auszugeben. Allerdings optimiert mir der Compiler bei der Options -Os 
Code weg, was er nicht machen sollte.

Hier mal ein Auszug aus der .c Datei:
[c]
     uint16_t t=0xffee;
     lcd_hex(t>>8);
     lcd_putc(' ');
     lcd_hex(t);
     lcd_putc(' ');

void lcd_hex(uint8_t d)
{
     uint8_t high,low;
     high = d >> 4; // copy high nibble
     low = d & ~((1<<7) | (1<<6) | (1<<5) | (1<<4)); // copy low nibble
     if(high > 9)
     {
          high += 'A';
          high -= '9';
          high -= 1; // in hex A or greater move to right position in 
matrix
     }
     high += '0'; // map 0x00 to char '0'
     lcd_write(high);

     if(low > 9)
          low += ('A' - '9' -1);
     low += '0';
     lcd_write(low);
}
[\c]

Was er aber nur ausgibt ist "FFE " aber er sollte "FF EE " ausgeben. Hat 
hier einer eine Idee woran das liegt?
Wenn ich die Option -Os durch -O0 ersetze klappt es wunderbar.
Nutze WinAVR 20070525.

Liebe Grüsse
Matthias

von Walter (Gast)


Lesenswert?

ich denke der Fehler ist nicht im gezeigten Code-Abschnitt, sondern in 
der Send-Routine ans LCD, da ist irgendein Delay was nicht passt

von Stefan Salewski (Gast)


Lesenswert?

void lcd_hex(uint8_t d)

erwartet ein Byte, aber
lcd_hex(t);
schickt zwei Byte, da
uint16_t t=0xffee;

Kann so etwas gut gehen?
Ich würde so eher nicht programmieren.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Wie sehen lcd_write() und lcd_putc() aus; ist da vielleicht ein 
Timingproblem?

Normalerweise muss die Optimierung eingeschaltet sein, damit die 
LCD-Timings exakt wie vorgegeben sind. Möglicherweise stimmen die Zeiten 
nicht und es werden Zeichen verschluckt, wenn die Ausgabefunktionen zu 
schnell nacheinander aufgerufen werden. Das würde sich entschärfen, wenn 
die Optimierung ausgeschaltet wird. Klappt eine schnelle Ausgabe eines 
"Hello World" Textes mit eingeschalteter Optimierung?

Wieso wird in lcd_hex() lcd_write() statt lcd_putc() benutzt?

Sowas macht mich misstrauisch. Nicht dass die eine Funktion für STRINGS 
statt für ZEICHEN ist. Ist aber eher eine unwahrscheinliche Möglichkeit, 
denn einiges bei der Ausgabe stimmt ja.

Als letzte Möglichkeit fällt mir ein, dass du ein gemischtes 
C/Assembler-Listing erzeugen lassen kannst und diese *.LSS Datei angeben 
lönntest. Dann sieht man welchen Code GCC aus deinem Quelltext 
produziert hat.

von Matthias F. (idefix)


Angehängte Dateien:

Lesenswert?

Hab hier mal den Code angehängt.

@Stefan Salewski
Das mit dem abschneiden ist Absicht, die hex Funktion soll immer 8-bit 
Werte bekommen. Deswegen wird beim erste Aufruf ja auch das ganze um 
8-bit verschoben.

@stefb
"Hello world" gibt er ohne Probleme aus.

von Walter (Gast)


Lesenswert?

wieso verwendest du ein Mal lcd_write und ein Mal lct_putc???????????

dein lcd_putc baut sich aus lcd_write UND delay zusammen!!

von Stefan Salewski (Gast)


Lesenswert?

Matthias Fechner schrieb:
>Das mit dem abschneiden ist Absicht

In der Tat, gcc akzeptiert

# include <stdint.h>
void test(uint8_t i)
{

}

int main(void)
{
  uint16_t j;
  test(j);
  return 0;
}

Ich dachte eigentlich, dass man korrekt
   test((uint8_t) j);
schreiben müsste.

Wieder was gelernt, wenngleich ich bei der Notation mit Type-Cast 
bleiben werde.

von Matthias F. (idefix)


Lesenswert?

Hi Walter,

Walter wrote:
> wieso verwendest du ein Mal lcd_write und ein Mal lct_putc???????????
>
> dein lcd_putc baut sich aus lcd_write UND delay zusammen!!

oh man, manchmal sieht man de Wald echt vor lauter Bäumen nicht. Vielen 
Dank für den Tip, jetzt klappt es wunderbar.

VLG
Matthias

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.