Forum: Compiler & IDEs Optimierungsproblem bei avr-gcc


von Daniel B. (dbuergin)


Angehängte Dateien:

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:
1
char buffer[20];
2
char h_buf[5];
3
uint8_t x =0;
4
uint8_t h_count = 0;
5
char uart_buffer[128];
6
uint32_t speed_g = 0;
7
uint32_t speed_n = 0;
8
uint32_t km_1 = 0;
9
10
// 1.39 Knoten/h sind ca. 2.574 Km/h
11
12
sprintf(buffer,"1.39");
13
14
while (1) {
15
16
  sprintf(uart_buffer,"\r\nBuffer: %s\r\n",buffer);
17
          uart_puts(uart_buffer);
18
19
  x =0;
20
  h_count = 0;
21
  km_1 = 0;
22
23
  // Zuerst mal alles vor dem Punkt (.) in den Hilfsbuffer h_buf schreiben, dabei die
24
  // Anzahl der Stellen in h_count zaehlen
25
26
  h_count = 0;
27
  while (buffer[x] != '.') {
28
     h_buf[h_count++] = buffer[x++];
29
  }
30
31
  // Nun auf Grund der gefundenen Stellen den Ganzahlteil der Variablen Speed fuellen
32
  // Achtung, h_count beginnt bei 0 also bedeutet 2, dass 3 Stellen vor dem Komma waren ;-)
33
34
  if (h_count == 3) {
35
     speed_g = (h_buf[0]-48)*100 + (h_buf[1]-48)*10 + (h_buf[2]-48);
36
  } else if (h_count == 2) {
37
     speed_g = (h_buf[0]-48)*10 + (h_buf[1]-48);
38
  } else {
39
     speed_g = (h_buf[0]-48);
40
  }
41
42
 // Jetzt kommt der Nachkommateil, der scheint immer zweistellig zu sein
43
44
 x++; // zuerst eines weiter, wir stehen sonst auf dem Dezimalpunkt
45
46
 speed_n = (buffer[x++]-48)*10;
47
 speed_n += (buffer[x++]-48);
48
49
 // Nun haben wir den Nachkommateil in "speed_n"
50
51
 sprintf(uart_buffer,"Step1: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
52
 uart_puts(uart_buffer);
53
54
 // Nun die Knoten in Km/h umrechnen
55
 // Bei 1.39 Knoten sollte speed_g = 1
56
 //                        speed_n = 39 sein
57
 //
58
 // 1 * 1852        = 1852 m/h
59
 // (39 * 1852)/100 = 722.28 m/h (.28 faellt weg)
60
 //                 = 2574 m/h
61
 // ergibt speed_g  = 2
62
 //        speed_n  = 574
63
64
 km_1 = (speed_g * 1852) + ((speed_n * 1852) / 100);
65
66
 sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
67
 uart_puts(uart_buffer);
68
69
 speed_g = km_1 / 1000;
70
 speed_n = km_1 % 1000;
71
72
 sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
73
 uart_puts(uart_buffer);
74
75
 ms_sleep(3000);
76
}

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:
1
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

von Andreas K. (a-k)


Lesenswert?

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

Wenn Windows, dann unbedingt aktuelle Version von WinAVR verwenden.

von Daniel B. (dbuergin)


Lesenswert?

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

von Daniel B. (dbuergin)


Lesenswert?

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

von Daniel B. (dbuergin)


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

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.