Forum: Compiler & IDEs Compiler-Fehler bei ISR


von Manfred B (Gast)


Lesenswert?

Hallo zusammen,

zur Zeit arbeite ich mich in die C-Programmierung ein.
Bisher habe ich in Assembler programmiert.

Nachfolgend ein kleiner Programm-Rumpf:


#include <avr/interrupt.h>


ISR(SIG_INTERRUPT0)
{
  // TODO Code
}


ISR(SIG_INTERRUPT1)
{
  // TODO Code
}


int main()
{
  // TODO Interrupts initialisieren
  sei();

  // Endlos-Schleife
  while (1)
  {
    // TODO Code
  }

  return (0);
}



Mein Problem ist folgendes:
Wenn ich ISR(SIG_INTERRUPT1) auskommentiere, läuft der Compiler
problemlos durch.
Wenn ich beide ISRs programmiere, habe ich den Compiler-Fehler:
../TestISR.c:14: error: redefinition of 'ISR'

Meine Frage: Warum? Was mache ich falsch? Wie kann ich mehrere ISRs
programmieren.


Vielen Dank für eure geschätzte Hilfe.

Gruss Manfred

von smay4finger. (Gast)


Lesenswert?

ISR ist eine Registerdefinition.

Interrupts werden so programmiert:

  SIGNAL(SIG_INTERRUPT0) {
     /* hier was sinnvollen */
  }

mfg, Stefan.

P.S. PEBCAC

von Manfred B (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort:

Habe den Code abgeändert:

#include <avr/interrupt.h>


SIGNAL(SIG_INTERRUPT0)
{
}


SIGNAL(SIG_INTERRUPT1)
{
}


int main()
{
  while (1)
  {
  }

  return (0);
}


Die Fehlermeldung hat auch geändert:
../TestISR2.c:10: error: redefinition of 'SIGNAL'


Das Problem ist somit geblieben.

Gruss Manfred

von Magnus Müller (Gast)


Lesenswert?

@PEBCAC:

>> ISR ist eine Registerdefinition.
>> ...
>> Interrupts werden so programmiert:
>>   SIGNAL(SIG_INTERRUPT0) {
>>      /* hier was sinnvollen */
>>   }

Falsch! Zusammen mit der neuen Version von WinAVR wurde "SIGNAL"
durch "ISR" ersetzt. "SIGNAL" wird aber aus Kompatibilitätsgründen
bis auf weiteres noch von WinAVR unterstützt (aber nicht mehr
empfohlen).


@Manfred:

Leider unterschlägst Du uns deinen eigentlichen "TODO Code". Ich gehe
davon aus, dass irgendwo in diesem (nicht geposteten) Code eine
geschweifte Klammer, oder ein Semikolon fehlt. Mir hatten derartige
Flüchtigkeitsfehler in der Vergangenheit bereits die tollsten
Fehlermeldungen beschert ;)

Also: Suche in deinem Code noch einmal GENAU nach fehlenden/falschen
Zeichen. Vergiss auch nicht, eingebundene Makros und Routinen /
Bibliotheken zu checken.

Viel Erfolg,
Magnetus

von smay4finger. (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

am besten das mal lesen. SIGNAL ist scheinbar nicht mehr ganz richtig,
das wurde in neueren avrlibc-Versionen durch ISR ersetzt.

mfg, Stefan.

von smay4finger. (Gast)


Lesenswert?

> Falsch!

Naja, falsch, darüber kann man sich streiten. Wie Du weiter bemerkst:

> "SIGNAL" wird aber aus Kompatibilitätsgründen bis auf weiteres noch
von WinAVR unterstützt

Bin halt nicht mehr auf dem allerneuestem Stand. Aber der Hinweis mit
dem "TODO-Code" ist schon richtig, ist auch noch eine Möglichkeit.

mfg, Stefan.

von Manfred B (Gast)


Lesenswert?

Um den Fehler einzuschränken, sieht mein Code sehr bescheiden aus.

Hier der VOLLSTÄNDIGE Code:


#include <avr/interrupt.h>


SIGNAL(SIG_INTERRUPT0)
{
  int i = 1;
  int j;
  j = i;
}


SIGNAL(SIG_INTERRUPT1)
{
  int i = 1;
  int j;
  j = i;
}


int main()
{
  while (1)
  {
    int i = 1;
    int j;
    j = i;
  }

  return (0);
}


Nebenbei: Ich setze AVR-Studio 4.12:460 udn WinAVR ein.

Gruss Manfred

von A.K. (Gast)


Lesenswert?

Richtigen Compiler verwenden. Mit "gcc" statt "avr-gcc", also x86-
statt AVR-Compiler gibt's ebendiesen Fehler.

von Manfred B (Gast)


Lesenswert?

Sorry, ich meinte natürlich:

#include <avr/interrupt.h>


ISR(SIG_INTERRUPT0)
{
  int i = 1;
  int j;
  j = i;
}


ISR(SIG_INTERRUPT1)
{
  int i = 1;
  int j;
  j = i;
}


int main()
{
  while (1)
  {
    int i = 1;
    int j;
    j = i;
  }

  return (0);
}


Hatte den Vorschlag von smay4finger getestet, und dann die Änderung
nicht mehr rückgängig gemacht.

von Magnus Müller (Gast)


Lesenswert?

@Manfred:

Räusper Na ja... ich glaube immer noch nicht, dass DAS dein
vollständiger Code sein soll schmunzel

Aber um beim Thema zu bleiben: Ich gehe davon aus dass du den Code, so
wie du ihn oben geposted hast, nicht per Copy&Paste hier reingesetzt,
sondern separat hier eingetippt hast.

Worauf ich hinaus will: überprüfe ob am Ende deiner Blöcke auch
wirklich eine GESCHLOSSENE geschweifte Klammer steht.

Beispiel (richtig):

   SIGNAL(SIG_INTERRUPT0)
   {
     int i = 1;
     int j;
     j = i;
   }


Beispiel (falsch):

   SIGNAL(SIG_INTERRUPT0)
   {
     int i = 1;
     int j;
     j = i;
   {            <-- FEHLER !

von Manfred B (Gast)


Angehängte Dateien:

Lesenswert?

Richtigen Compiler einstellen?

Habe einen ScreenShut erstellt (Neues Projekt erstellen).


@A.K: Kannst Du prüfen, ob dies der richtige Compiler ist?
Wenn die Info nicht genügt, wo kann den richtigen einstellen?


Gruss Manfred

von Εrnst B. (ernst)


Lesenswert?

Screenshot als .doc? Tss... Wer soll sich das denn anschauen?

Ist der Ziel-uC Typ richtig definiert? ansonsten passen die SIG_...
defines nicht, könnte genau diese Felhermeldung provozieren.
(sollte dann aber eine Warnung von avr/io.h generiert werden)

/Ernst

von Manfred B (Gast)


Lesenswert?

Ja, Leute, ich suche nämlich schon lange am Fehler...

Ich weiss, der Code macht ja nicht Sinn, aber um den Fehler
einzuschränken habe ich ihn bewusst einfach gemacht.

Den Code habe ich WIRKLICH mit Copy&Paste reinkopiert:

#include <avr/interrupt.h>


ISR(SIG_INTERRUPT0)
{
  int i = 1;
  int j;
  j = i;
}


ISR(SIG_INTERRUPT1)
{
  int i = 1;
  int j;
  j = i;
}


int main()
{
  while (1)
  {
    int i = 1;
    int j;
    j = i;
  }
  return (0);
}


Und ich habe WIRKLICH folgende Fehlermeldung:
../TestISR2.c:13: error: redefinition of 'ISR'


Vielen Dank für eure Hilfe
Gruss Manfred

von Magnus Müller (Gast)


Lesenswert?

@Manfred:

Du schreibst auch

>> ISR(SIG_INTERRUPT0)

...und...

>> ISR(SIG_INTERRUPT1)

Wenn ich mich nicht irre gibt es zusammen mit der Einführung von
"ISR" auch neue Namen für die Vektoren (die neuen enden jetzt alle
mit "_vect"). Schlag nochmal im "avr-libc Manual.pdf" nach. Dort
sind alle(?) neuen Namen aufgeführt.

Kannst Du auch nochmal deinen verwendeten AVR nennen? Dann könnten wir
Deinen Code mal probehalber compilieren.

Thx
Magnetus

von Εrnst B. (ernst)


Lesenswert?

Füg folgende Zeilen nach dem #include <avr/interrupt.h> ein:
1
#ifndef _AVR_IOXXX_H_
2
#  error "AVR-Typ nicht definiert"
3
#endif

Und schau, ob sich die Fehlermeldung ändert.

/Ernst

von Manfred B (Gast)


Lesenswert?

@Magnetus,

ja, ich werde nochmals nachschlagen.



Ich setze einen ATmega8 ein.

Wäre nett, wenn Du das mal compilieren könntest.

/Manfred

von Εrnst B. (ernst)


Lesenswert?

Compiliert bei mir einwandfrei, der Code von oben...
(Copy&Paste in .c file)

Jetzt wäre vielleicht deine GCC-Versionsnummer & avr-libc
Versionsnummer hilfreich.


/Ernst

von Manfred B (Gast)


Lesenswert?

Ich habe in der Doku noch was gefunden: INTERRUPT().
Da tönt auch logisch und kompiliert sogar.

Nochmals an alle: DANKE für die Hilfe.

Ich wünsche eine gute Nacht. Gruss Manfred



#include <avr/interrupt.h>
#include <avr/signal.h>


INTERRUPT(SIG_INTERRUPT0)
{
  int i = 1;
  int j;
  j = i;
}


INTERRUPT(SIG_INTERRUPT1)
{
  int i = 1;
  int j;
  j = i;
}


int main()
{
  while (1)
  {
    int i = 1;
    int j;
    j = i;
  }

  return (0);
}

von Εrnst B. (ernst)


Lesenswert?

Das ist ja interressant, scheint eine recht alte version zu sein, die Du
da benutzt...

bei mir besteht die avr/signal.h aus nur einer Zeile (minus
Header+Kommentar):

#warning "This header file is obsolete.  Use <avr/interrupt.h>."


/Ernst

von Magnus Müller (Gast)


Lesenswert?

@Manfred:

Achtung "INTERRUPT" verhält sich anders als "ISR" (siehe Doku)

von Magnus Müller (Gast)


Lesenswert?

Moin moin...

Also... ich hab den Code auch nochmal compiliert und (eigentlich)
keinen Fehler gehabt. Einzige Ausnahme: Bei mir gabs Mecker, weil "int
main()" eigentlich "int main(void)" lauten sollte.

Ich hab darauf hin mal versucht, durch bewusstes Einfügen der von mir
genannten Flüchtigkeitsfehler, deinen Fehler zu provozieren. Aber
leider scheint mein Geschwätz wohl doch nichts damit zu tun gehabt
haben rotwerd ;)

Nun zum Unterschied zwischen "INTERRUPT" und "ISR" (bzw.
"SIGNAL"):

Deklarierst du deinen Interrupthandler als "ISR" bzw. "SIGNAL" wird
dieser Handler mit gestperrten Global Interrupt Enable ausgeführt, was
verhindert, dass dein Handler von einem anderen Interrupt unterbrochen
wird. Erst beim Rücksprung aus dem Handler werden die Interrupts wieder
freigegeben.

Deklarierst du deinen Interrupthandler als "INTERRUPT" werden die
Interrupts gleich zu Beginn des Handlers wieder freigegeben. Dein
Handler kann dann von anderen Interrupts unterbrochen werden.

Gruß
Magnetus

von peter dannegger (Gast)


Lesenswert?

Du mußt noch io.h einbinden, sonst erkennt er ja die Interruptvektoren
nicht.


Peter

von Manfred B (Gast)


Lesenswert?

Hallo zusammen

ich habe mir die neuste Version von WinAVR (20060125) heruntergeladen.

Compiliert einwandfrei.


Die vorher installierte Version war aus dem 1. Quartal 2005.


Gruss Manfred



[GESCHLOSSEN]

von Birger* (Gast)


Lesenswert?

Eine weitgehend überflüssige Diskussion - leider. Hättste gleich mal ein
paar Fakten erzählt, wär das viel schneller gegangen. Merken für die
Zukunft.

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.