www.mikrocontroller.net

Forum: Compiler & IDEs Volatile Variablen und Optimierung


Autor: Bernd Brandmeier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe da ein Problem mit dem GCC Compiler im Zusammenhang
mit Volatile-deklarierten Variablen und Code-Optimierung.

Interesant ist die Zeile: 'while(cinw_ptr == cinr_ptr);' in der
Funktion 'ReadComDaten'. Während dieser While-Schleife wird auf
das Eintreffen eines neuen Bytes vom COM-Port gewartet. Dieses
wird per Interruptroutine empfangen und in einen Empfangspuffer
eingetragen. Dabei wird der Zeiger 'cinr_ptr' um 1 erhöht, woran
man dann erkennen kann das ein neues Byte angekommen ist.

Das Problem ist, das die Variablen 'cinw_ptr' und 'cinr_ptr'
zwar global als Volatile deklariert sind, der Compiler es aber so
übersetzt
das die Variablen in Register geladen werden und dann nur noch mit
diesen
gearbeitet wird und nicht mehr mit den eigentlichen Variablen. (siehe
unten)
Ich dachte eigentlich das mit 'Volatile'-Variablen genau das
verhindert werden
soll.

Vielleicht hat jemand eine Idee, was da schief läuft.

MfG
Bernd

C-Code:

volatile uchar *cinw_ptr, *cinr_ptr, *coutw_ptr, *coutr_ptr;

uchar ReadComData(void)
  {
  uchar data;

  while(cinw_ptr == cinr_ptr);  // warten auf ein neues Byte ...

  data = *cinr_ptr;
  cinr_ptr++;

  .... weiterer Code .....
  }


Daraus macht der Compiler, mit Optimierung -Os:

uchar ReadComData(void)                            // (warte und) lese
Zeichen vom Com-Port
  {
     2ba:  80 91 62 00   lds  r24, 0x0062
     2be:  90 91 63 00   lds  r25, 0x0063
     2c2:  e0 91 60 00   lds  r30, 0x0060
     2c6:  f0 91 61 00   lds  r31, 0x0061
  uchar data;

  while(cinw_ptr == cinr_ptr);
// warte auf Zeichen
     2ca:  8e 17         cp  r24, r30
     2cc:  9f 07         cpc  r25, r31
     2ce:  e9 f3         breq  .-6        ; 0x2ca
  weiterer Code ....

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich bin mir absolut unsicher aber ich würde mal behaupten das sich das
volatile nicht auf den Pointer selbst sondern auf die Adresse bezieht
wohin der Pointer zeigt.

Matthias

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> while(cinw_ptr == cinr_ptr);

Warum denkst Du sollte sich der Wert des Pointers ändern, bloss weil
das Byte auf das er zeigt sich ändert?

Wie das heutige c't ja schon sagt, wir leben in der Sternchen-Ära,
also bitte ein paar hübsche Sternchen in dieses Statement einstreuen.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, das war Mist.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias hat recht. Korrekt:

char *volatile cinw_ptr,
     *volatile cinr_ptr,
     *volatile coutw_ptr,
     *volatile coutr_ptr

oder besser, weil lesbarer:

typedef char *char_ptr;
volatile char_ptr cinw_ptr, cinr_ptr, coutw_ptr, coutr_ptr;

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das ist wie bei const.

"const int * p" deklariert einen Zeiger, der auf einen konstanten
Wert zeigt. Der Zeiger selbst darf verändert werden, aber nicht der
Wert auf den er zeigt.
"int * const p" dagegen deklariert einen konstanten Zeiger, der auf
einen nicht-konstanten Wert zeigt.

volatile verhält sich syntaktisch in den meisten Fällen wie const (ist
beides ein "modifier"), daher brauchst du wohl sowas:
typedef uchar * volatile v_ptr;
v_ptr cinw_ptr, cinr_ptr, coutw_ptr, coutr_ptr;


Sollte ich mich irren, bitte ich um Korrektur. :-)

Autor: Bernd Brandmeier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Herren, Hut ab !

der Erfolg gibt euch Recht.
Jetzt wo es einem erklärt wird, klingt es irgendwie logisch ...

Danke noch mal für die schnelle Hilfe

Bernd

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> volatile verhält sich syntaktisch in den meisten Fällen wie const
> (ist beides ein "modifier"), ...

Sachlich richtig (und das Ergebnis zeigt es ja auch), kleine formale
Korrektur: beides sind type *qualifier*s.  (ISO C99 kennt noch einen
dritten, der nur in Funktionsdeklarationen und nur für Zeiger
auftauchen kann, "restricted".)

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg: Danke, wieder was gelernt. :)

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.