www.mikrocontroller.net

Forum: Compiler & IDEs Warnung in GCC


Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gemeinde,

ich habe ein kleines Problem mit dem GCC. Er spuckt mir die drei 
Warnungen aus.

../Hupe_GCC.c:2145: warning: passing arg 2 of `Seconds2BCD' discards 
qualifiers from pointer target type
../Hupe_GCC.c:2149: warning: passing arg 2 of `Int2BCD' discards 
qualifiers from pointer target type
../Hupe_GCC.c:2150: warning: passing arg 2 of `Int2BCD' discards 
qualifiers from pointer target type

Als globale Variable ist

volatile uint8_t tx_buffer[7];  // buffer for data paket to external 
display

definiert.

Die drei Warnungen werden bei diesen Funktionsaufrufen generiert.

  Seconds2BCD(display_time, tx_buffer);
  Int2BCD(goals_B, tx_buffer+2);
  Int2BCD(goals_W, tx_buffer+3);

welche die folgenden Funktionen aufrufen.

void Int2BCD(uint8_t data, uint8_t *buffer)
{
  uint16_t tmp;

  tmp = data % 10;
  data = data / 10;
  *buffer=(data <<4) | tmp;
}

void Seconds2BCD(uint16_t data, uint8_t *buffer)
{
  uint16_t tmp, tmp2;

  tmp = data % 600;
  data = data / 600;
  tmp2= data<< 4;              // tens minutes

  data = tmp % 60;
  tmp  = tmp / 60;
  *buffer= tmp2 | tmp;          // ones minutes
  buffer++;

  tmp = data % 10;
  data = data / 10;
  *buffer= (data <<4) | tmp;        // tens and ones seconds
}

Ideen?

Ich arbeite mit AVR Studio 4.12, Service Pack 4 und WinAVR 20060421

MfG
Falk

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du schmeißt bei der Übergabe des Zeigers an die Funktion das "volatile"
weg ("volatile" ist ein "type qualifier", genauso wie "const" und in
C99 jetzt neu "restricted").

Ich hatte schonmal hier erläutert, dass und warum volatile auf Arrays
praktisch weder sinnvoll noch notwendig ist.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg Wunsch

>Du schmeißt bei der Übergabe des Zeigers an die Funktion das "volatile"
>weg ("volatile" ist ein "type qualifier", genauso wie "const" und in
>C99 jetzt neu "restricted").

Aha.

>Ich hatte schonmal hier erläutert, dass und warum volatile auf Arrays
>praktisch weder sinnvoll noch notwendig ist.

Link?
Es geht darum, dass das Array als Sendepuffer dür RS232 arbeitet, sprich 
dass im Hauptprogramm der Puffer gefüllt wird und im ISR dann gelesen 
und gesendet. Ich nehme an dass Arrays sowieso nicht lokal gepuffert 
werden und immer direkt zurückgeschrieben werden, oder?

MFG
Falk

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, ich hätte vielleicht den ersten Schritt vor dem zweiten machen 
sollen und das Forum nach volatile abgrasen. Hab ich nun gemacht und das 
Ergebnis ist, dass ich volatile auch in die Parameterdefinition der 
Funktionen bringen sollte?

MFG
Falk

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk wrote:

> ... das
> Ergebnis ist, dass ich volatile auch in die Parameterdefinition der
> Funktionen bringen sollte?

Ich würde es lieber ganz weglassen.  Wenn du die ISR mit dem
Hauptprogramm synchronisieren musst, dann nimm eine einzelne
volatile deklarierte (uint8_t-)Variable dafür.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg Wunsch (dl8dtl)

> ... das
> Ergebnis ist, dass ich volatile auch in die Parameterdefinition der
> Funktionen bringen sollte?

>Ich würde es lieber ganz weglassen.  Wenn du die ISR mit dem

Kann es komische Effekte verursachen?

>Hauptprogramm synchronisieren musst, dann nimm eine einzelne
>volatile deklarierte (uint8_t-)Variable dafür.

Mach ich schon, aber hier ist es umgekehrt. Ich schreibe im Hauptprogamm 
Daten in den Puffer und schalte am Ende den UDRE Interrupt ein, welcher 
dann auch sofort angesprungen wird. D.h. in dem Moment muss garantiert 
der Inhalt von tx_buffer stimmen.

MfG
Falk

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>D.h. in dem Moment muss garantiert der Inhalt von tx_buffer stimmen.

Das passt schon...

>Ich schreibe im Hauptprogamm Daten in den Puffer

Mache ich auch meist so. Oder bastel mir ein "putchar(unsigned char c)", 
das sich um das Beschreiben des Puffers kümmert. Allerdings arbeite ich 
ohne Pointer, sondern mit Indizes.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> D.h. in dem Moment muss garantiert
> der Inhalt von tx_buffer stimmen.

Dann starte die Aussendung mit einem Funktionsaufruf.

Eine andere Alternative wäre eine "memory barrier", aber die ist
natürlich stark compilerabhängig:

__asm __volatile(""::: "memory");

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rahul, der Trollige

>>D.h. in dem Moment muss garantiert der Inhalt von tx_buffer stimmen.
>Das passt schon...

Dein Wort in Gottes Gehörgang ;-)

>Ich schreibe im Hauptprogamm Daten in den Puffer

>Mache ich auch meist so. Oder bastel mir ein "putchar(unsigned char c)",

Warum soll ich für ne simple Variablenzuweisung eine Funktion schreiben?

>das sich um das Beschreiben des Puffers kümmert. Allerdings arbeite ich
>ohne Pointer, sondern mit Indizes.

Aber kaum als Parameter in ner Funktion.

@Jörg Wunsch

>> D.h. in dem Moment muss garantiert
>> der Inhalt von tx_buffer stimmen.

>Dann starte die Aussendung mit einem Funktionsaufruf.
>Eine andere Alternative wäre eine "memory barrier", aber die ist
>natürlich stark compilerabhängig:
>__asm __volatile(""::: "memory");

Was spricht gegen volatile? Ich finde es arg Overkill wegen so einem 
Problemchen mit extra Funktionen oder gar kryptischen Compilertricks zu 
arbeiten. Aber das scheint der Fluch von C zu sein, die Hackersprache 
ist nie wirklich erwachsen geworden . . .

MfG
Falk

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was spricht gegen volatile?

Dass du damit alle Optimierungen auf buffer verhinderst, auch die,
die man gar nicht verhindern muss.  Gewissermaßen eine Pessimierung.

Die extra Funktion schafft einen sogenannten sequence point, und an
diesem müssen alle globalen Variablen rückgeschrieben sein (da sie
in der Funktion benutzt werden könnten).  Das ist meiner Meinung
sogar dann der Fall, wenn die Funktion selbst so simpel ist, dass
sie der Compiler am Ende inline expandiert => du hast optimalen
Code, und den sogar garantiert.

Ganz davon abgesehen ist es im Sinne der Modularisierung guter
Programmierstil, wenn man das Handling der UART (und damit auch die
Freigabe des UDRE) dem UART-Modul codeseitig überlässt, auch wenn
es sich nur um ein einzelnes Register handelt, das es dafür zu
beschreiben gilt.  Das fördert die Abstraktion, und der Code ließe
sich einfacher auf einen anderen Prozessor (mit anderer UART-Hardware)
portieren.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, das klingt einleuchtend und überzeugend. Ich werde einen 
Funktionsaufruf für die UART schreiben.

Danke.

MFG
Falk

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Warum soll ich für ne simple Variablenzuweisung eine Funktion schreiben?

>>das sich um das Beschreiben des Puffers kümmert. Allerdings arbeite ich
>>ohne Pointer, sondern mit Indizes.

>Aber kaum als Parameter in ner Funktion.

Meine putchar sieht halt so aus:

void putchar(unsigned char c)
{
   sendbuffer[sendwritepointer++]=c;
   sendwritepointer %= Buflength; // Überlauf verhindern
   if (!(USR & (1<<UDRIE)) USR |= (1<<UDRIE); // Hies das Ding USR?
}
Da das USART wensentlich langsamer als das Hauptprogramm ist, wird alles 
schön in den Puffer geschrieben und per ISR abgearbeitet.
In der ISR wird UDRIE gelöscht, sobald der sendwritepointer == 
sendreadpointer ist - beide Zeiger also an der gleichen Stelle stehen...
Die Pointer sind global volatile, wie der Puffer auch, vereinbart.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die Pointer sind global volatile, wie der Puffer auch, vereinbart.

Sorry, aber den Puffer als flüchtig zu markieren versucht Jörg ihm doch 
gerade auszureden...

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sorry, aber den Puffer als flüchtig zu markieren versucht Jörg ihm doch
>gerade auszureden...

Dann halte ich mich lieber raus... (die "Pointer" sind auch nichts 
anderes als Indizes eines array, keine *...)

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um die Pointer geht's nicht, Du schriebst, dass Du den Puffer selbst 
'volatile' machst...

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Um die Pointer geht's nicht, Du schriebst, dass Du den Puffer selbst
>'volatile' machst...

Ich sollte mir angewöhnen, die "Vorschau"-Funktion zu benutzen: Dann 
hätte ich Jörgs Post noch lesen können und mir meine Beiträge sparen 
können.
Das "volatile" bei arrays werde ich jetzt einfach mal weglassen.

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.