mikrocontroller.net

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


Autor: Sebastian Z. (sebastian_z)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Roland Praml (pram)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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]

Autor: Sebastian Z. (sebastian_z)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-))
/* uart.c
**********************************************************************************
**                                        **
** Projekt:      UART-Ansteuerung                      **
**                                        **
** Entwickler:    Sebastian                    **
**                                        **
** Version:      01.00.01                          **
**                                        **
** Änderungsdatum:  02.06.2008                          **
**                                        **
**********************************************************************************
*/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "uart.h"



volatile data uart_ctrl;

volatile char uart_char;

volatile char temp_strg[max_strg_length + 1];
volatile char uart_strg[max_strg_length + 1];



ISR(USART_RXC_vect)
{
  uart_char = UDR;
  if(uart_ctrl.strg_complete == 0)
  {
    put2string(uart_char);
  }
}


ISR(USART_TXC_vect)
{
}



void uart_init(void)
{
  UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<TXCIE) | (1<<RXCIE);
  UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
  UBRRH = UBRR_BAUD >> 8;
  UBRRL = UBRR_BAUD & 0xFF;
  sei();
}


void uart_c_out(char zeichen)
{
  while(!(UCSRA & (1<<UDRE)));
  UDR = zeichen;
}


void uart_s_out(char *zeichen)
{
  while (*zeichen)
  {
    uart_c_out(*zeichen);
    zeichen++;
  }
}


void put2string(char c)
{
  if(c == CR || uart_ctrl.strg_count > max_strg_length)
  {
    temp_strg[uart_ctrl.strg_count] = 0x00;
    uart_ctrl.strg_complete = 1;
    uart_ctrl.strg_count = 0;
    strcpy(uart_strg,temp_strg);
  }
  else
  {
    temp_strg[uart_ctrl.strg_count] = c;
    uart_ctrl.strg_count++;
  }
}


char uart_get_c(void)
{
  return uart_char;
}


char* uart_get_s(void)
{
    uart_ctrl.strg_complete = 0;
    return &uart_strg;
}

und die .h datei
/*uart.h
**********************************************************************************
**                                        **
** Projekt:      UART-Ansteuerung                      **
**                                        **
** Entwickler:    Sebastian                    **
**                                        **
** Version:      01.00.01                          **
**                                        **
** Änderungsdatum:  02.06.2008                          **
**                                        **
**********************************************************************************
*/


typedef struct
{
  unsigned strg_count:7;
  unsigned strg_complete:1;
} data;


#define BAUDRATE 9600UL
#define UBRR_BAUD ((F_CPU/(16UL*BAUDRATE))-1)

#define max_strg_length 16

#define CR 0x0D
#define LF 0x0A


// !Interne Funktionsaufrufe!
void put2string(char c);


// !Externe Funktionsaufrufe!
void uart_init(void);
void uart_c_out(char zeichen);
void uart_s_out(char *zeichen);
char uart_get_c(void);
char* uart_get_s(void);

und das test-programm
// Sebastian


#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include "uart.h"

uint8_t a,b;
char *string;
char saved_strg[17];

void keys(void)


{
  if(!(PINA & 0x01) >= 1)
  {
    if(a >= 1)
    {
      uart_s_out("GetChar");
      uart_c_out(LF);
      uart_c_out(uart_get_c());
      uart_c_out(CR);
      a = 0;
    }
  }

  else if((PINA & 0x01) >= 1) a = 1;

  if(!(PINA & 0x80) >= 1)
  {
    if(b >= 1)
    {
      uart_s_out("GetStrg");
      uart_c_out(LF);
      string = uart_get_s();
      strcpy(saved_strg, string);
      uart_s_out(saved_strg);
      uart_c_out(CR);
      b = 0;
    }
  }

  else if((PINA & 0x01) >= 1) b = 1;

}



int main(void)
{
  DDRA = 0x00;
  PORTA = 0xFF;


  uart_init();
  uart_s_out("Atmega Terminal Ready");
  uart_c_out(CR);
  uart_c_out(LF);

  while(1)
  {
    keys();
  }
  return 0;
}

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ../test.c:38: warning: implicit declaration of function 'strcpy'

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

Autor: Sebastian Z. (sebastian_z)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian Pfanner (db1pf)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Wolfgang Mües (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wolfgang Mües (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.