[AVR] (Fehlerhafte) Codeoptimierung bei 32bit-Variablen

OP #1058626
Lesenswert?
• ▲
▼
Hi alle,

sitze hier zur Zeit an einem Code, der den 10 bit ADC-Wert nach mV 
umwandeln soll. Die Rechnung ist da ja prinzipiell einfach:
mv = 5000 * adc / 1024
gekürzt:
mv = 625 * adc / 128
Da adc nun aber bereits 10 bit breit ist, 625 nochmal 10 bit, könnte das 
Ergebnis also 20 bit breit werden. Das passt nicht mehr in einen uint16, 
also dachte ich, ich nehme einfach einen uint32 her.

Die Umwandlungsroutine sieht dann jetzt so aus:
1
uint16_t adc2voltage(uint16_t adc_value)
2
{
3
  return (625 * (uint32_t)adc_value) / 128;
4
}

Verifizieren tu ich die Rechnung durch Ausgabe des Wertes auf einem 
LC-Display und einer vorrangehenden Umwandlung des Ergebnisses in einen 
String mit folgender Funktion:
1
void dec2str(int32_t wert, uint8_t anzahl, uint8_t fuell, uint8_t *dest)
2
{
3
  uint8_t i;
4
  uint8_t sign = fuell;
5
  if (wert < 0) {
6
    sign = '-';
7
    wert *= -1;
8
  }
9
  for (i = 0; i < anzahl; i++)
10
  {
11
    dest[anzahl - i - 1] = '0' + (wert % 10);
12
    wert /= 10;
13
  }
14

15
  for (i=0; i<(anzahl - 1); i++)
16
  {
17
    if (dest[i] == '0')
18
      dest[i] = fuell;
19
    else
20
      break;
21
  }
22
  dest[0] = sign;
23
}
24

25
int main() {
26
...
27
  uint32_t mv = adc2voltage(adc_value); // adc_value kommt von ADC
28

29
  uint8_t str[9];
30
  str[8] = 0;
31
  dec2str(adc_value, 8, ' ', str);
32
  lcd_gotoxy(12, 0);
33
  lcd_puts(str);
34
...
35
}

Wenn ich nun die Codeoptimierung aus habe (-O0), dann funktioniert der 
Code auch einwandfrei und es wird die korrekte Spannung angezeigt. Wenn 
ich die Codeoptimierung aktiviere (egal welches Level), kommen ziemlich 
krumme Werte raus. Aktuell zeigt mir das Display für einen ADC-Wert von 
50 einen Spannungswert von 64049. Bei 49 kommt 62767.

Wenn ich bei aktivierter Optimierung allerdings adc_valze einen festen 
Wert vor der Umwandlung zuordne (zB adc_value = 50), dann stimmt das 
Ergebnis auch wieder (244 mV), allerdings scheint der Compiler dann die 
Umwandlungsroutine einfach komplett wegzuoptimieren (nach meinen kurzen 
einblicken in das Listung zu urteilen ;) ).

Version des AVR-GCC ist 4.3, irgendwo meine ich mal gelesen zu haben, 
dass es da Probleme geben könnte ... Kommt nun wirklich der GCC einfach 
nicht mit den 32 bit klar, oder ist da sonst irgendwas von mir falsch?

Grüße,
Chris
OP #1058667
Lesenswert?
• ▲
▼
Hi Tobi,

> Die Variablen, die nicht optimiert werden sollen, mit "volatile"
> deklarieren!
das habe ich schon versucht ... sowohl bei der Deklaration der 
adc_value-Variablen im Hauptcode, als auch mit ner extra 
zwischen-Variablen in der adc2voltage-Routine ... Hat beides nichts 
geändert.

Grüße,
Chris
OP #1058669
Lesenswert?
• ▲
▼
Hi A.K.,

> Eine ungepatchte 4.3.0 hat einen ganz üblen Bug bei 32bit Multiplikation
> mit Konstanten, und exakt das ist hier der Fall.
Dann nehme ich mal an, es gibt bereits einen Patch ... Dh ich muss 
entweder warten, bis der Patch es in die Repositories geschafft hat oder 
aus den Quellen kompilieren? Gefällt mir eigentlich beides nicht ;)
Das betrifft aber nur den GCC selber, also keine der andren Tools in der 
Toolchain?

Chris

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.