Forum: Mikrocontroller und Digitale Elektronik Programm 2 mal kompilieren um Warnings zu entfernen?


von Sebastian Z. (Gast)


Lesenswert?

Hallo,

ich benutze WinAvr 20071221 mit AVRStudio 4.13 Built 571.
Nun Habe ich bei mehreren Projekten schon den Effekt gehabt, dass ich 
beim erstmaligem kompilieren Warnings bekam. Wenn ich dann einfach 
nochmal kompiliert habe, waren die Warnings verschwunden und das 
Built-Fenster sagte:
 - Build succeeded with 0 Warnings... -
Wenn ich dann im Projekt etwas geändert habe, traten die Warnings 
sporadisch wieder auf, waren aber beim 2. kompilieren wieder weg. Das 
Programm funktioniert dann auch.

Mir ist aufgefallen, dass das immer bei Projectebn passiert, in denen 
ich mindestens 2 .c dateien mit der jeweiligen .h datei habe.
Also so:
pwm.h und pwm.c und dazu dann die test.c in der #include pwm.h steht.
In der pwm.c steht somit keine int main(void)
jetzt weiß ich nicht, ob es beim kompilieren einen Unterschied macht, 
welches Fenster gerade aktiv ist.

Jedenfalls ist mir dieses Phänomen schon bei mehreren Projecten 
aufgefallen.

Über Tipps oder Hilfen wäre ich echt dankbar

Grüße
Sebastian

von Roland P. (pram)


Lesenswert?

also normal wird aus jeder .c Datei ein Objekt erzeugt (compiliert)
Die Object-files werden zum schluss gelinkt woraus das eigentliche 
Programm entsteht.
Wenn sich die .c Datei nicht geändert hat, wird das Objectfile nicht neu 
erstellt und es erscheinen deshalb keine Warnings.

Gruß
Roland

von lkmiller (Gast)


Lesenswert?

>Über Tipps oder Hilfen wäre ich echt dankbar
Wir auch ;-)
Was kommen denn da für Fehlermeldungen/Warnings?

[Glaskugelmodus=on]
>...pwm.h und pwm.c und dazu dann die test.c in der #include pwm.h steht...
Sieh dir mal das Thema Deklaration und Definition an. Vielleicht hilft 
das weiter.
[Glaskugelmodus=off]

von Sebastian Z. (Gast)


Lesenswert?

Hallo,
danke schon mal für die Tipps bisher.
Dadurch habe ich herausgefunden, dass irgendetwas im Sourcecode nicht 
stimmt.
Daher hänge ich ihn mal mit den Warnings an.
Ich wusste nicht, dass beim compilieren das Objectfile nicht immer neu 
geschrieben wird. Kann man das irgendwo einschalten, so dass die 
Warnings immer auftreten?
Mich wundert nur, dass das Programm läuft.
Also hier der Code (Bin aber noch in den Anfänge des Programmierens, 
daher bitte nicht zuuuuu Kritisch sein ;-))
1
/* uart.c
2
**********************************************************************************
3
**                                        **
4
** Projekt:      UART-Ansteuerung                      **
5
**                                        **
6
** Entwickler:    Sebastian                    **
7
**                                        **
8
** Version:      01.00.01                          **
9
**                                        **
10
** Änderungsdatum:  02.06.2008                          **
11
**                                        **
12
**********************************************************************************
13
*/
14
15
16
#include <avr/io.h>
17
#include <avr/interrupt.h>
18
#include <stdint.h>
19
#include "uart.h"
20
21
22
23
volatile data uart_ctrl;
24
25
volatile char uart_char;
26
27
volatile char temp_strg[max_strg_length + 1];
28
volatile char uart_strg[max_strg_length + 1];
29
30
31
32
ISR(USART_RXC_vect)
33
{
34
  uart_char = UDR;
35
  if(uart_ctrl.strg_complete == 0)
36
  {
37
    put2string(uart_char);
38
  }
39
}
40
41
42
ISR(USART_TXC_vect)
43
{
44
}
45
46
47
48
void uart_init(void)
49
{
50
  UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<TXCIE) | (1<<RXCIE);
51
  UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
52
  UBRRH = UBRR_BAUD >> 8;
53
  UBRRL = UBRR_BAUD & 0xFF;
54
  sei();
55
}
56
57
58
void uart_c_out(char zeichen)
59
{
60
  while(!(UCSRA & (1<<UDRE)));
61
  UDR = zeichen;
62
}
63
64
65
void uart_s_out(char *zeichen)
66
{
67
  while (*zeichen)
68
  {
69
    uart_c_out(*zeichen);
70
    zeichen++;
71
  }
72
}
73
74
75
void put2string(char c)
76
{
77
  if(c == CR || uart_ctrl.strg_count > max_strg_length)
78
  {
79
    temp_strg[uart_ctrl.strg_count] = 0x00;
80
    uart_ctrl.strg_complete = 1;
81
    uart_ctrl.strg_count = 0;
82
    strcpy(uart_strg,temp_strg);
83
  }
84
  else
85
  {
86
    temp_strg[uart_ctrl.strg_count] = c;
87
    uart_ctrl.strg_count++;
88
  }
89
}
90
91
92
char uart_get_c(void)
93
{
94
  return uart_char;
95
}
96
97
98
char* uart_get_s(void)
99
{
100
    uart_ctrl.strg_complete = 0;
101
    return &uart_strg;
102
}

und die .h datei
1
/*uart.h
2
**********************************************************************************
3
**                                        **
4
** Projekt:      UART-Ansteuerung                      **
5
**                                        **
6
** Entwickler:    Sebastian                    **
7
**                                        **
8
** Version:      01.00.01                          **
9
**                                        **
10
** Änderungsdatum:  02.06.2008                          **
11
**                                        **
12
**********************************************************************************
13
*/
14
15
16
typedef struct
17
{
18
  unsigned strg_count:7;
19
  unsigned strg_complete:1;
20
} data;
21
22
23
#define BAUDRATE 9600UL
24
#define UBRR_BAUD ((F_CPU/(16UL*BAUDRATE))-1)
25
26
#define max_strg_length 16
27
28
#define CR 0x0D
29
#define LF 0x0A
30
31
32
// !Interne Funktionsaufrufe!
33
void put2string(char c);
34
35
36
// !Externe Funktionsaufrufe!
37
void uart_init(void);
38
void uart_c_out(char zeichen);
39
void uart_s_out(char *zeichen);
40
char uart_get_c(void);
41
char* uart_get_s(void);

und das test-programm
1
// Sebastian
2
3
4
#include <avr/io.h>
5
#include <stdint.h>
6
#include <stdlib.h>
7
#include "uart.h"
8
9
uint8_t a,b;
10
char *string;
11
char saved_strg[17];
12
13
void keys(void)
14
15
16
{
17
  if(!(PINA & 0x01) >= 1)
18
  {
19
    if(a >= 1)
20
    {
21
      uart_s_out("GetChar");
22
      uart_c_out(LF);
23
      uart_c_out(uart_get_c());
24
      uart_c_out(CR);
25
      a = 0;
26
    }
27
  }
28
29
  else if((PINA & 0x01) >= 1) a = 1;
30
31
  if(!(PINA & 0x80) >= 1)
32
  {
33
    if(b >= 1)
34
    {
35
      uart_s_out("GetStrg");
36
      uart_c_out(LF);
37
      string = uart_get_s();
38
      strcpy(saved_strg, string);
39
      uart_s_out(saved_strg);
40
      uart_c_out(CR);
41
      b = 0;
42
    }
43
  }
44
45
  else if((PINA & 0x01) >= 1) b = 1;
46
47
}
48
49
50
51
int main(void)
52
{
53
  DDRA = 0x00;
54
  PORTA = 0xFF;
55
56
57
  uart_init();
58
  uart_s_out("Atmega Terminal Ready");
59
  uart_c_out(CR);
60
  uart_c_out(LF);
61
62
  while(1)
63
  {
64
    keys();
65
  }
66
  return 0;
67
}

Hier die Warnings:
../test.c:38: warning: implicit declaration of function 'strcpy'
../test.c:38: warning: incompatible implicit declaration of built-in 
function 'strcpy'


Es ist hier zwar nicht die beschriebene PWM-Routine, aber das ist das 
aktuellste Projekt von mir bei dem die Warnings auftreten.
Leider bin ich mit meinen Kenntnissen noch nicht so weit, dass ich den 
Fehler finde. Wahrscheinlich was ganz simples und ich sehe es einfach 
nicht.

Wenn mich jemand drauf aufmerksam machen würde, wäre ich sehr dankbar.
Grüße
Sebastian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> ../test.c:38: warning: implicit declaration of function 'strcpy'

In test.c fehlt #include <string.h>

von Sebastian Z. (Gast)


Lesenswert?

Ok, danke,
wenn ich die Syntax und die Beispiele zu strcpy mal Zeile für Zeile 
angeschaut hätte, hätte ich drauf kommen müssen.
Muss mich entschuldigen, meine eigene Doofheit ;-)
Jetzt sind die beiden Warnings weg.
Aber dafür habe ich !3! neue, die ich wirklich nicht verstehe:

../uart.c: In function 'put2string':
../uart.c:83: warning: passing argument 1 of 'strcpy' discards 
qualifiers from pointer target type
../uart.c:83: warning: passing argument 2 of 'strcpy' discards 
qualifiers from pointer target type
../uart.c:102: warning: return from incompatible pointer type

Ich verstehe die nicht, weil ich doch in den Funktionen ausschließlich 
mit char arbeite. Und in der letzten Funktion einen Zeiger auf char, bzw 
die Speicheradresse des Strings zurückgebe!?

Oder bin ich wieder zu blind??? ....oder doch vielleicht doof??

Grüße
Sebastian

von Florian P. (db1pf)


Lesenswert?

Hallo,

die Lösung hat Rufus schon geschrieben, hier noch ein Hinweis zum 
Compilieren:
Das AVR-Studio erstellt für den Comiliervorgang eine Makefile. Make ist 
so intelligent, dass es erkennt welche C-Datei geändert wurde und dass 
diese dann auch neu Comiliert werden müssen. Wenn du jetzt zweimal auf 
'Comilieren' klickst, werden beim ersten mal die Dateien Compiliert und 
die Warnings erscheinen. Wenn du zum zweiten mal auf Compilieren 
klickst, erkennt make dass es nix zu tun gibt. Es wird nix Compiliert 
und es gibt somit auch keine Warnings. Schau dir mal dazu genau die 
Build-Ausgabe im AVR-Studio an. Da kannst du das auch erkennen.

Du kannst das komplette (neue) erstellen aber auch erzwingen:
Es gibt im Menü den Punkt 'Make clean' oder 'Projekt bereinigen' (oder 
ähnlich). Da werden dann alle object-Dateien gelöscht und beim nächsten 
Compilieren sollten die Warnings alle wieder auftauchen.

Hoffe ich konnte dir helfen,
Grüße,
Florian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die neuen Warnungen haben damit zu tun, daß die von Dir an strcpy 
übergebenen char-Pointer volatile sind, strcpy selbst aber nicht so 
deklariert ist, daß es volatile -Pointer erwartet.

Also wird der "Qualifier" volatile weggeworfen (to discard).

von Wolfgang Mües (Gast)


Lesenswert?

Wenn der Compiler einen ERROR meldet, ist er nicht in der Lage, ein 
Object-File zu erstellen. Deshalb wird beim nächsten Versuch auch die 
C-Datei nochmal kompiliert.

Bei einer WARNING kann der Compiler eine Object-Datei erstellen. Dadurch 
wird er beim nächsten Mal die Object-Datei nicht noch einmal erstellen, 
und die Warning verschwindet.

Beim GNU-Compiler gibt es die Option "-Werror" "threat all Warnings as 
Errors". Vielleicht findest Du bei Deinem Compiler auch so eine Option?

Die Fehlermeldung mit dem volatile bekommst Du am einfachsten weg, indem 
Du den Parameter auf den gewünschten Typ castest.

von Wolfgang Mües (Gast)


Lesenswert?

Ich sehe übrigens in Deinem Code KEINEN Grund, die Variablen volatile zu 
deklarieren.

Volatile macht nur Sinn, wenn eine Variable gleichzeitig von mehreren 
Tasks verwendet wird, und ein Task in einer Schleife auf Änderung pollt. 
Diese Situation hast Du in Deiner Software gar nicht.

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.