www.mikrocontroller.net

Forum: Compiler & IDEs SIGNAL geht INTERRUPT nicht ???


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits,
folgendes Problem:
Daten die über die serielle Schnittstelle den MC erreichen sollen ans
Display geschrieben werden. Das geht mit folgendem CODE Schnipsel
prima:

SIGNAL(SIG_UART_RECV)
{
  putchar_lcd(inp(UDR));
}

Warum aber hauts nicht hin wenn man anstelle von SIGNAL INTERRUPT
schreibt?? Die Zeichen kommen so langsam an den MC dass die
Displayroutine mit Sicherheit abgearbeitet ist bevor das nächste byte
kommt....

Freu mich auf eure Antworten!!
Vielen Dank

Christian

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum aber hauts nicht hin wenn man anstelle von SIGNAL INTERRUPT
> schreibt?

Weil Du den Unterschied zwischen beiden entweder nicht verstanden hast
und/oder das Datenblatt nicht richtig gelesen.  Besonders
SIG_UART_RECV ist absolut ungeeignet für INTERRUPT(), das das
schlagartig zu einer endlosen Rekursion führt.

Autor: Eugen Dischke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ma ne frage ich hab bisher angenommen, das es kein unterschied gibt zw
interrupt und signal kann mich ma einer aufklären
MfG eugen

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab gerade mal die AVR-Libc durchgeschaut. Hab aber keine eindeutige
zuweisung gefunden.
Aber grundsätzlich: Wenn ich mich nicht täusche, so ist Signal() ein
ganz normaler Interrupt. Wenn du jedoch Interrupt() schreibst, so ist
der erste ASM-Befehl in der Routiene sei. Also gleich nach dem Betreten
der Interruptschleife werden die Interrupts wieder freigegeben. Wenn
aber das Interrupt-Flag von der Hardware noch nicht gelöscht wurde, so
wird der Interrupt sofort wieder aufgerufen. Das geht so lange bis dein
Stack überläuft.
Ich weiß nicht wozu man die Interrupt() braucht, ich habs bis jetzt
immer von Hand gemacht: Interruptroutiene mit Signal(), dann das
dazugehörige Interrupt-Flag gelöscht und erst dann wieder eine Globale
Interruptfreigabe.

Gruß, Florian

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber grundsätzlich: Wenn ich mich nicht täusche, so ist Signal() ein
> ganz normaler Interrupt. Wenn du jedoch Interrupt() schreibst, so
> ist der erste ASM-Befehl in der Routiene sei.

Genau so ist es (außer daß sich beide komplett GROSS schreiben -- C
unterscheidet zwischen Groß-/Kleinschreibung).

Ich verstehe auch gar nicht, warum das aus der Doku so schwierig
herauszulesen sein soll:

SIGNAL():

Introduces an interrupt handler function that runs with global
interrupts initially disabled.

INTERRUPT():

Introduces an interrupt handler function that runs with global
interrupts initially enabled. This allows interrupt handlers to be
interrupted.

> Ich weiß nicht wozu man die Interrupt() braucht, ...

Die Grundregel #1 ist: wenn Du nicht weißt, wofür Du es brauchst, dann
brauchst Du es nicht. ;-)

In der Tat braucht man das wohl eher für Spezialfälle, bei denen man
keine Zeit damit vergeuden will, die Interrupts sofort wieder
freizugeben, um andere (zeitkritische) Interrupts nicht zu verzögern.
Logischerweise kann man es nur bei Interrupts benutzen, die sich nicht
aufgrund des Hardware-Flags sofort wieder selbst auslösen würden.

Meiner Meinung nach sind sie etwas unglückselig benannt, so daß zu
viele Leute geneigt sind, INTERRUPT() überhaupt in Betracht zu ziehen.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen und vielen Dank für eure Antworten!!!

ich konnte das Problem jetzt recht erfolgreich ohne "Interrupt"
(sondern mit Signal) lösen, allerdings ist mir immer noch nicht klar
warums nicht funktioniert hat, auch wenn ich innerhalb der Interrupt
routine lediglich den Empfangswert der seriellen schnittstelle in eine
andere Variable kopiert habe??

Macht aber nix - brauchs ja jetzt nicht mehr .....

Danke für eure Hilfe und alles Gute fürs neue Jahr!!

Christian

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich konnte das Problem jetzt recht erfolgreich ohne "Interrupt"
> (sondern mit Signal) lösen, allerdings ist mir immer noch nicht klar
> warums nicht funktioniert hat, auch wenn ich innerhalb der Interrupt
> routine lediglich den Empfangswert der seriellen schnittstelle in
> eine andere Variable kopiert habe?

Weil Du nur mit trial & error arbeitest und leider immer noch nicht
verstanden hast, was Du denn überhaupt tust.

,,lediglich den Empfangswert ... kopiert'' ist halt exakt die
Operation (lesen von UDR), die die anhängige Interruptbedingung wieder
zurücknimmt.  Wenn Du zuvor aber bereits die globalen Interrupts
wieder freigibst (wie es in INTERRUPT() ja passiert), dann wird sofort
nach dem SEI ein neuer Interrupt ausgelöst (für das gleiche Ereignis),
was unweigerlich zum Stacküberlauf führt.

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.