Forum: Compiler & IDEs Warnung in GCC


von Falk (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Falk (Gast)


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

von Falk (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Falk (Gast)


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

von Rahul, der Trollige (Gast)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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");

von Falk (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Falk (Gast)


Lesenswert?

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

Danke.

MFG
Falk

von Rahul, der Trollige (Gast)


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.

von Patrick D. (oldbug) Benutzerseite


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...

von Rahul, der Trollige (Gast)


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 *...)

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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

von Rahul, der Trollige (Gast)


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.

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.