mikrocontroller.net

Forum: Compiler & IDEs Optimierungsproblem bei avr-gcc


Autor: Daniel B. (dbuergin)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Bin am verzweifeln. Wenn ich mein Program ohne Optimierung übersetze und 
laufen lasse, ist alles ok, wenn ich es mit "-Os" übersetze und laufen 
lassen geht's in die Hose.
Problemstellung: In dem Buffer "buffer" steht der variable Wert Knoten/h 
aus einem GPS (NMEA 0183) Satz. Diesen möchte ich in Km/h umrechnen, 
wenn möglich ohne Float-Werte zu benutzen.

avr-gcc : 4.3.0
avr-libc: 1.6.2
CPU     : ATMEGA128 (Maveric IB Board von http://www.bdmicro.com)

Das Problem habe ich soweit eingegrenzt, als dass es etwas mit einer 
Multiplikation zu tun hat. Hier eine abgewandelte Version meines Codes 
als Beispiel:

char buffer[20];
char h_buf[5];
uint8_t x =0;
uint8_t h_count = 0;
char uart_buffer[128];
uint32_t speed_g = 0;
uint32_t speed_n = 0;
uint32_t km_1 = 0;

// 1.39 Knoten/h sind ca. 2.574 Km/h

sprintf(buffer,"1.39");

while (1) {

  sprintf(uart_buffer,"\r\nBuffer: %s\r\n",buffer);
          uart_puts(uart_buffer);

  x =0;
  h_count = 0;
  km_1 = 0;

  // Zuerst mal alles vor dem Punkt (.) in den Hilfsbuffer h_buf schreiben, dabei die
  // Anzahl der Stellen in h_count zaehlen

  h_count = 0;
  while (buffer[x] != '.') {
     h_buf[h_count++] = buffer[x++];
  }

  // Nun auf Grund der gefundenen Stellen den Ganzahlteil der Variablen Speed fuellen
  // Achtung, h_count beginnt bei 0 also bedeutet 2, dass 3 Stellen vor dem Komma waren ;-)

  if (h_count == 3) {
     speed_g = (h_buf[0]-48)*100 + (h_buf[1]-48)*10 + (h_buf[2]-48);
  } else if (h_count == 2) {
     speed_g = (h_buf[0]-48)*10 + (h_buf[1]-48);
  } else {
     speed_g = (h_buf[0]-48);
  }

 // Jetzt kommt der Nachkommateil, der scheint immer zweistellig zu sein

 x++; // zuerst eines weiter, wir stehen sonst auf dem Dezimalpunkt

 speed_n = (buffer[x++]-48)*10;
 speed_n += (buffer[x++]-48);

 // Nun haben wir den Nachkommateil in "speed_n"

 sprintf(uart_buffer,"Step1: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
 uart_puts(uart_buffer);

 // Nun die Knoten in Km/h umrechnen
 // Bei 1.39 Knoten sollte speed_g = 1
 //                        speed_n = 39 sein
 //
 // 1 * 1852        = 1852 m/h
 // (39 * 1852)/100 = 722.28 m/h (.28 faellt weg)
 //                 = 2574 m/h
 // ergibt speed_g  = 2
 //        speed_n  = 574

 km_1 = (speed_g * 1852) + ((speed_n * 1852) / 100);

 sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
 uart_puts(uart_buffer);

 speed_g = km_1 / 1000;
 speed_n = km_1 % 1000;

 sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
 uart_puts(uart_buffer);

 ms_sleep(3000);
}

Output ohne Optimierung:

Buffer: 1.39
Step1: g: 1 n: 39 km_1: 0
Step2: g: 1 n: 39 km_1: 2574
Step3: g: 2 n: 574 km_1: 2574

Output mit Optimierung (-Os):

Step1: g: 1 n: 39 km_1: 0
Step2: g: 1 n: 39 km_1: 0
Step3: g: 0 n: 0 km_1: 0

Warum funktioniert die Berechnung:
km_1 = (speed_g * 1852) + ((speed_n * 1852) / 100);
unter der Optimierung nicht ? Ich habe alle möglichen Varianten 
versucht, aber keine klappt. Bereits ein "km_1 = speed_g * 1852" ergibt 
0 in km_1 ? Auch 1852L oder 1852UL in der Berechnung nützt nichts. 
Irgendwie suche ich wohl am völlig falschen Ort ? Braucht das noch 
andere Compiler/Linker Optionen als nur "-Os" ?

Für einen kleinen Wink mit dem Zaunpfahl wäre ich äusserst dankbar ;-)

Daniel

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

Bewertung
0 lesenswert
nicht lesenswert
Lass mich raten: ungepatcher GCC 4.3.0? Der ist nicht benutzbar.

Wenn Windows, dann unbedingt aktuelle Version von WinAVR verwenden.

Autor: Daniel B. (dbuergin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, an was sehe ich das ? gcc-avr_4_3_0-2_i386.dep für Ubuntu aus dem 
Intrepid Archiv geladen.

Autor: Daniel B. (dbuergin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das passt, bei aktuellsten WinAVR funktioniert das Ganze. Möchte aber 
weiterhin auf Linux bleiben ;-) Welche Version ist da die Beste ?

Autor: Daniel B. (dbuergin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh Mann, downgrad auf 4.2.2 und alles ist paletti. Nach 25 Jahren 
Informatik sollte man eigentlich wissen, dass man Pakete 
nicht-produktiven Distributionen nicht einsetzen sollte ;-)

Auf jeden Fall besten Dank für die Hilfe.

Daniel

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.