Forum: Compiler & IDEs Ist "warning" nach dem Compilieren wichtig?


von Neuling (Gast)


Lesenswert?

Hi, ich habe mir ein kleines Programm geschrieben, mit dem ich Tasten 
(PortB1-4) auswerten möchte und als Resultat eine LED aufleuchten lassen 
mag, die an einem anderen Port hängt (PortC1-4).

Ich habe in die jeweilige Schalterfunktion ein _delay gesetzt, weil ich 
ja einen Moment sehen will, wie die Lampe aufleuchtet und dann wieder 
ausgehen soll. Gleichzeitig müsste so auch durch die Verzögerung die 
Taste "entprellt" werden. Ich möchte die Wartezeit 2,5 Sekunden (2500 
ms) aufleuchten lassen. Nun kommt beim Compilieren ein Warning:

"warning "F_CPU not defined for <util/delay.h>" [-Wcpp]"

Kann man die Warnung einfach "übergehen"?

1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/delay.h>
6
7
#include "uart.h"
8
// #include "uart.c"
9
#include <stdio.h>
10
11
/* define CPU frequency in Mhz here if not defined in Makefile */
12
#ifndef F_CPU
13
#define F_CPU 1000000UL
14
#endif
15
16
/* 9600 baud */
17
#define UART_BAUD_RATE      9600
18
19
void Schalter1 (void)
20
{
21
  PORTC |= (1 << PORTC0);  // Bit 0 setzen
22
  _delay_ms(2500);
23
  PORTC &= ~(1<<PORTC0); // Bit 0 loeschen
24
}
25
void Schalter2 (void)
26
{
27
    PORTC |= (1 << PORTC1);  // Bit setzen
28
    _delay_ms(2500);
29
    PORTC &= ~(1<<PORTC1); // Bit loeschen
30
} 
31
32
void Schalter3 (void)
33
{
34
  PORTC |= (1 << PORTC2);  // Bit setzen
35
  _delay_ms(2500);
36
  PORTC &= ~(1<<PORTC2); // Bit loeschen
37
}
38
39
void Schalter4 (void)
40
{
41
  PORTC |= (1 << PORTC3);  // Bit setzen
42
  _delay_ms(2500);
43
  PORTC &= ~(1<<PORTC3); // Bit loeschen
44
}
45
46
47
int main(void)
48
{
49
  // eigene Variablen
50
  uint8_t Pinabfrage;
51
  
52
  // Baudrate einstellen und BITS in UBBR setzen
53
  // uart_init (UART_BAUD_SELECT (UART_BAUD_RATE, F_CPU));
54
  
55
  // Datenrichtung festsetzen
56
  DDRB = 0x00;  // alles Eingänge
57
  DDRC = 0x3F;  // Pin 0-5 Ausgänge!
58
  
59
  // Interrupts einschalten
60
  // sei ();
61
    
62
  while (1)
63
  {
64
    Pinabfrage = PINB;
65
    
66
    if (Pinabfrage & (1<<PINB0)) 
67
    {
68
      Schalter1();
69
    }
70
    
71
    if (Pinabfrage & (1<<PINB1))
72
    {
73
      Schalter2();
74
    }
75
    
76
    if (Pinabfrage & (1<<PINB3))
77
    {
78
      Schalter3();
79
    }
80
    
81
    if (PINB & (1<<PINB4))
82
    {
83
      Schalter4();
84
    }
85
    
86
  }
87
}

: Verschoben durch Moderator
von holger (Gast)


Lesenswert?

>Kann man die Warnung einfach "übergehen"?

Nein.

/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 1000000UL
#endif

#include <util/delay.h>

von Lucas K. (lucas_k)


Lesenswert?

Diese Warnung sollte man nicht so einfach übergehen. Denn der delay 
errechnet aus F_CPU die anzahl an takte, die gewartet werden muss.

Verschiebe einfach die Definition von F_CPU vor die includes. Dann ist 
dem Präprozessor bekannt, wie groß F_CPU ist und es kommt auf keinen 
Fall zu Fehlern.

von (prx) A. K. (prx)


Lesenswert?

Neuling schrieb:
> Kann man die Warnung einfach "übergehen"?

Nur wenn es dir völlig egal ist, ob die Delays stimmen oder 
grottenfalsch sind. Andernfalls wärs nützlich, F_CPU vor delay.h zu 
definieren.

von Ulrich U. (uli-dd-70)


Lesenswert?

Hallo,

definiere F_CPU einfach BEVOR Du delay.h einbindest. Hier machts die 
Reihenfolge. Ignorieren ist schlecht, weil sonst durchaus Timings nicht 
stimmen könnten, die in delay.h hinterlegt sind.

Gruß Uli

von Coder (Gast)


Lesenswert?

Selbst bei warnings sollte man sich Gedanken, auch wenn es irgendwie 
funktionieren sollte. Schau mal bezgl. F_CPU in die delay.h und delay.c.

von Jim M. (turboj)


Lesenswert?

> "warning "F_CPU not defined for <util/delay.h>" [-Wcpp]"
> Kann man die Warnung einfach "übergehen"?

Nur, wenn man delay() nicht benutzt - dann braucht man util/delay.h aber 
auch nicht zu includen.

Du musst in Deinem Makefile in den CFLAGS das F_CPU Symbol definieren.

von Neuling (Gast)


Lesenswert?

Lucas K. schrieb:
> Verschiebe einfach die Definition von F_CPU vor die includes. Dann ist
> dem Präprozessor bekannt, wie groß F_CPU ist und es kommt auf keinen
> Fall zu Fehlern.

cool, danke für die schnellen Antworten, jetzt klappts auch fehlerfrei 
mit dem Compilieren.

von fragt sich warum... (Gast)


Lesenswert?

Das Verschieben der #define Anweisung ist nur bedingt eine gute Idee. 
Mit nur einer Quelltextdatei ist das kein Problem. Bei größeren 
Projekten können sich hier schnell Fehler einschleichen.

Besser ist es, solche #defines in einen separaten Header zu legen. Und 
wenn es sich um Bibliotheksfunktionen handelt und diese keine 
projektspezifischen Includes vorsehen, sollten solche Definitionen per 
Makefile und Compiler-Switch vorgenommen werden. Ich glaube mich daran 
zu erinnern, daß gerade beim avrgcc der Weg über das Makefile gerne 
genommen wird.

Fehler die darauf resultieren, daß zwei unterschiedliche Definitionen 
wirksam werden, sind außerordentlich undankbar und kosten viel Zeit.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

fragt sich warum... schrieb:
> Und wenn es sich um Bibliotheksfunktionen handelt und diese keine
> projektspezifischen Includes vorsehen, sollten solche Definitionen per
> Makefile und Compiler-Switch vorgenommen werden.

Makros wirken nicht auf Bibliotheken, es sei denn sie werden mit 
gesetztem Makro neu generiert.

von fragt sich warum... (Gast)


Lesenswert?

Johann L. schrieb:
> fragt sich warum... schrieb:
>> Und wenn es sich um Bibliotheksfunktionen handelt und diese keine
>> projektspezifischen Includes vorsehen, sollten solche Definitionen per
>> Makefile und Compiler-Switch vorgenommen werden.
>
> Makros wirken nicht auf Bibliotheken, es sei denn sie werden mit
> gesetztem Makro neu generiert.

Hab' mich schlampig ausgedrückt - keine Bibliotheken selbst, sondern 
beliebiger externer Code, der eigentlich nicht modifiziert werden 
sollte, um die Verwendbarkeit in unterschiedlichen Projekten/Plattformen 
und die problemlose Aktualisierung zu gewährleisten. Dabei kann es sich 
um komplette Quelltexte handeln oder um Bibliotheken, welche Header 
Dateien mitbringen die in Abhängigkeit der Makrodefinitionen die 
Erzeugung unterschiedlichen Codes bewirken können. Ich denke letzteres 
ist in dem konkreten Fall gegeben.

von Neuling (Gast)


Lesenswert?

eine andere Frage hab ich nochmal - wenn ich die Stepfunktion im 
Debugger mache, hällt dann der Computer auch bei der Delay-Funktion an 
und macht die Pause durch? Weil mein Problem - an der Stelle 
delay(2500ms) hält der Computer einfach für eine Weile an und zwar 
mehrere Minuten. Vielleicht hab ich mich aber auch verreichet. Laut 
Angabe im Tutorial ist bei der Funktion _delay_ms die Zeit in 
Millisekunden anzugeben, also 2500ms = 2,5 Sekunden. Vielelicht hab ich 
mich aber auch verreichnet? Oder macht der Debugger "blödsinn"?

von Stefan E. (sternst)


Lesenswert?

Neuling schrieb:
> Vielelicht hab ich
> mich aber auch verreichnet? Oder macht der Debugger "blödsinn"?

Debuggen mit der Ziel-Hardware oder dem Simulator?
Vermutlich letzteres, denn der Simulator läuft nicht in Echtzeit, 
sondern ist erheblich langsamer.

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


Lesenswert?

Neuling schrieb:
> Weil mein Problem - an der Stelle
> delay(2500ms) hält der Computer einfach für eine Weile an und zwar
> mehrere Minuten.

Ja, das hängt damit zusammen, dass der Debugger intern einzelne
CPU-Schritte machen muss, bis er feststellt, dass der aktuelle
program counter schließlich mal einen Wert hat, der hinter der
delay-Zeile liegt.  Das delay selbst wird nämlich vom Compiler
inline aufgelöst, um möglichst wenig zusätzlichen Overhead zu
haben, das ist also keine Funktion, die tatsächlich gerufen wird.

Du solltest also besser einen breakpoint dahinter setzen und dann
bis dahin arbeiten lassen.  (Für eine Simulation wiederum kommt
man am besten, wenn man die Delays gleich durch eigene Funktionen
ersetzt, die sofort weitermachen.)

von Neuling (Gast)


Lesenswert?

Ich danke Euch für Eure Antworten. Ich hab erst etwas gerätselt, ob ich 
einen Umrechnungsfehler gemacht hab und 2500ms nicht 2,5 Sekunden sind. 
Aber so liegt es dann doch am Compiler/Simulator :-)

von Karl H. (kbuchegg)


Lesenswert?

Neuling schrieb:
> Ich danke Euch für Eure Antworten. Ich hab erst etwas gerätselt, ob ich
> einen Umrechnungsfehler gemacht hab und 2500ms nicht 2,5 Sekunden sind.
> Aber so liegt es dann doch am Compiler/Simulator :-)

Du darfst nicht den Fehler machen, dein Zeitempfinden in der Simulation 
als Referenz zu benutzen.
Der Simulator führt über die Simulationszeit Buch und zeigt sie dir an. 
D.h. auch wenn der Simulator 5 Minuten laut deiner Armbanduhr rumrödelt, 
für dich relevant ist die Zeitangabe, die der Simulator als 
Simulationszeit ausgibt.

von Simon K. (simon) Benutzerseite


Lesenswert?

Neuling schrieb:
> /* define CPU frequency in Mhz here if not defined in Makefile */
> #ifndef F_CPU
> #define F_CPU 1000000UL
> #endif

Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch 
letztens erst.
Die Definition von F_CPU hat in keiner .c/.h Datei etwas zu suchen, 
sondern wird GLOBAL an EINER Stelle in den Projektoptionen festgelegt, 
damit dies beim Aufruf des Compilers mitübergeben wird und in allen 
Compilation Units eine konsistente F_CPU definiert ist.

Wenn sich die F_CPU ändert, klapper ich doch nicht jede .c/.h Datei ab 
und ändere das dort. Totaler Humbug. Sowas sollte verboten und aus 
Gegenwart und Historie des Internets gelöscht werden.

Das hat bisher nur einer hier richtig erwähnt:
Jim Meba schrieb:
>> "warning "F_CPU not defined for <util/delay.h>" [-Wcpp]"
>> Kann man die Warnung einfach "übergehen"?
>
> Nur, wenn man delay() nicht benutzt - dann braucht man util/delay.h aber
> auch nicht zu includen.
>
> Du musst in Deinem Makefile in den CFLAGS das F_CPU Symbol definieren.

von Hmm... (Gast)


Lesenswert?

Übrigens ist es grundsätzlich keine gute Idee, Warnungen des Compilers 
zu ignorieren. Hierfür gibt es sogar beim GCC Einstellungen, um mehr 
Warnungen bezüglich potentiell fehlerträchtiger Konstrukte zu generieren 
und diese sogar gleich als Fehler(!) zu behandeln.

Gerade beim Casten von verschiedenen Datentypen oder 
Gültigkeitsbereichen von Variablen kann einem das viel Zeit und Nerven 
bei der Fehlersuche ersparen.

von Tom K. (ez81)


Lesenswert?

Simon K. schrieb:
> Neuling schrieb:
>> /* define CPU frequency in Mhz here if not defined in Makefile */
>> #ifndef F_CPU
>> #define F_CPU 1000000UL
>> #endif
>
> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch
> letztens erst.

Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...

von delay (Gast)


Lesenswert?

Tom K. schrieb:
> Simon K. schrieb:
>> Neuling schrieb:
>>> /* define CPU frequency in Mhz here if not defined in Makefile */
>>> #ifndef F_CPU
>>> #define F_CPU 1000000UL
>>> #endif
>>
>> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch
>> letztens erst.
>
> Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...

Selbst schuld. Dafür benutzt man keine Delays.

von Simon K. (simon) Benutzerseite


Lesenswert?

delay schrieb:
> Tom K. schrieb:
>> Simon K. schrieb:
>>> Neuling schrieb:
>>>> /* define CPU frequency in Mhz here if not defined in Makefile */
>>>> #ifndef F_CPU
>>>> #define F_CPU 1000000UL
>>>> #endif
>>>
>>> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch
>>> letztens erst.
>>
>> Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...
>
> Selbst schuld. Dafür benutzt man keine Delays.

F_CPU hat ja nichts mit Delays zu tun, sondern kann man ja auch selbst 
benutzen um Timer zu konfigurieren.

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.