www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt ausgelöst, Funktion unterbrechen WIE?


Autor: Koblenzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend...

Ich habe eine Frage:

Habe ein Programm:
ISR (INT1_vect)
{
   //interruptroutine
   ...
   ...
   ...
}

int main(void)
{
   while(1)
   {
      funktion1();
      funktion2();
      funktion3();
   }
}
Beispiel:
es wird z.B. funktion2 bearbeitet und in der Zeit löst INT1 aus.
Wie kann ich, nachdem Interruptroutine beendet ist, SOFORT!!! funktion2
verlassen???

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum sollte man so etwas tun?

Das was so dringend erledigt werden soll, daß keine Zeit mehr bleibt, 
funktion2 fertig zu bearbeiten, kann doch in die Interruptroutine.

Wenn das nicht das Problem ist, dann beschreib mal genauer was du 
vorhast.

Autor: Koblenzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, Interruptroutine ist für Datentransfer zwischen FPGA und 
Mikrocontroller.
Interrupt wird ausgelöst, wenn /CS="0" ist und PINS für /RD und /WR für 
Datenrichtung (FPGA->uC, FPGA<-uC).
In main() werden Kommandos verarbeitet.
ein Bit im Datenbus (bei einen Komando) ist für "RESET" verantwortlich,
d.h. wenn der "1" ist muss aktuelle "Kommando" SOFORT! unterbrochen 
werden.
Sofort, weil es kann sehr schnell neues Befehl kommen.

p.S. sorry für mein Deutsch :)

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im einfachsten Fall setzt du in der ISR ein Flag und prüftst das Flag in 
der Funktion.

volatile unsigned char interrupt_ist_aufgetreten_funktion_sofort_abbrechen;

#define GGF_ABBRUCH_JETZT()                                      \
do {                                                             \
    if (interrupt_ist_aufgetreten_funktion_sofort_abbrechen)     \
    {                                                            \
        interrupt_ist_aufgetreten_funktion_sofort_abbrechen = 0; \
        return;                                                  \
    }                                                            \
} while(0)

ISR (INT1_vect)
{
   //interruptroutine
   interrupt_ist_aufgetreten_funktion_sofort_abbrechen = 1;
}

void funktion1(void)
{
    int i;
    for(i = 0; i < 10000; i++)
    {
        // ... mache irgendwas
        GGF_ABBRUCH_JETZT();
        // ... mache irgendwas anderes
        GGF_ABBRUCH_JETZT();
    }
}

int main(void)
{
   while(1)
   {
      funktion1();
      funktion2();
      funktion3();
   }
}


Autor: Koblenzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So habe ich mir auch das vorgestellt...
Ich dachte, dass es in "C" eine Standartmetode gibt.

MfG

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist abgrundtief hässlich und dringend davon abzuraten, aber so sollte 
das möglich sein:
#include <setjmp.h>

jmp_buf env;

int main(void)
{
   while(1)
   {
      if (!setjmp(env)) {
         funktion1();
         funktion2();
         funktion3();
      }
   }
}

ISR(INT1_vect)
{
   longjmp(env, 1);
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
setjmp - longjmp

Hmm. Was passiert da eigentlich mit dem Stack, bzw. dem Interrupt
Flag im SREG?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hatte ich vorsichtshalber kontrolliert: SREG wird dabei mit gesichert.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist abgrundtief hässlich

:-)

Dann doch lieber gleich einen Pin mit einem externen Interrupt-Eingang 
verbinden, aber keine ISR zuordnen. Pin aus der ISR auf high -> Full 
reset :-)

Irgendwie verstehe ich das nicht ganz. Die Auswertung der Kommandos wird 
doch irgendwelche "Seiteneffekte" haben, sprich, die Kommandos bewirken 
irgendwas. Ich kann mir nicht vorstellen, daß sich dieses "irgendwas" an 
jeder beliebigen Stelle abbrechen lässt, ohne das es ein 
Riesendurcheinander gibt.

Ohne definierte Aussprungpunkte aus den main-Funktionen, die eventuell 
auch noch unterschiedliche Aufräumarbeiten durchführen, dürfte das nicht 
machbar sein.

Zum anderen habe ich dich so verstanden, daß die ISR für den Empfang der 
Daten zuständig ist. Damit wird die doch immer aufgerufen, wenn ein 
Kommando kommt. Nur muß bei Erkennung von "Reset" alles vorherige 
verworfen werden.

Oliver
P.S. "Sofort" ist immer sehr relativ.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem Longjump geht, wenn man genau überblicken kann, was in
funktion[123] genau passiert.

Man muss sich sehr genau überlegen, was beim Abbruch der Funktion
alles passieren kann. Was passiert bspw., wenn in der Funktion ein
16-Bit-I/O-Register beschreibt und genau zwischen den beiden dafür
erforderlichen 8-Bit-Zugriffen abgebrochen wird? Komplett tabu sollte
der Longjump dann sein, wenn Bibliotheksfunktionen aufgerufen werden,
da man keinerlei Annahmen über deren Verhalten bei einem Abbruch
machen sollte.

Also ist das doch eher etwas für Verwegene.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Koblenzer wrote:
> Also, Interruptroutine ist für Datentransfer zwischen FPGA und
> Mikrocontroller.
> Interrupt wird ausgelöst, wenn /CS="0" ist und PINS für /RD und /WR für
> Datenrichtung (FPGA->uC, FPGA<-uC).
> In main() werden Kommandos verarbeitet.
> ein Bit im Datenbus (bei einen Komando) ist für "RESET" verantwortlich,
> d.h. wenn der "1" ist muss aktuelle "Kommando" SOFORT! unterbrochen
> werden.
> Sofort, weil es kann sehr schnell neues Befehl kommen.

Der AVR kann kein Slave auf dem Memorybus sein, also ist er der Master.

D.h. der AVR bestimmt, wann er was vom FPGA abholt.
Der FPGA muß die Daten solange puffern. Ein FPGA hat ja deutlich mehr 
SRAM als ein AVR.

Man kann aber auch in einen kleinen Puffer direkt im Interrupthandler 
einlesen. Memoryzugriffe sind ja doch recht fix.


Peter

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.