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


von Koblenzer (Gast)


Lesenswert?

Guten Abend...

Ich habe eine Frage:

Habe ein Programm:
1
ISR (INT1_vect)
2
{
3
   //interruptroutine
4
   ...
5
   ...
6
   ...
7
}
8
9
int main(void)
10
{
11
   while(1)
12
   {
13
      funktion1();
14
      funktion2();
15
      funktion3();
16
   }
17
}
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???

von der mechatroniker (Gast)


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.

von Koblenzer (Gast)


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 :)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Im einfachsten Fall setzt du in der ISR ein Flag und prüftst das Flag in 
der Funktion.
1
volatile unsigned char interrupt_ist_aufgetreten_funktion_sofort_abbrechen;
2
3
#define GGF_ABBRUCH_JETZT()                                      \
4
do {                                                             \
5
    if (interrupt_ist_aufgetreten_funktion_sofort_abbrechen)     \
6
    {                                                            \
7
        interrupt_ist_aufgetreten_funktion_sofort_abbrechen = 0; \
8
        return;                                                  \
9
    }                                                            \
10
} while(0)
11
12
ISR (INT1_vect)
13
{
14
   //interruptroutine
15
   interrupt_ist_aufgetreten_funktion_sofort_abbrechen = 1;
16
}
17
18
void funktion1(void)
19
{
20
    int i;
21
    for(i = 0; i < 10000; i++)
22
    {
23
        // ... mache irgendwas
24
        GGF_ABBRUCH_JETZT();
25
        // ... mache irgendwas anderes
26
        GGF_ABBRUCH_JETZT();
27
    }
28
}
29
30
int main(void)
31
{
32
   while(1)
33
   {
34
      funktion1();
35
      funktion2();
36
      funktion3();
37
   }
38
}

von Koblenzer (Gast)


Lesenswert?

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

MfG

von Andreas K. (a-k)


Lesenswert?

Ist abgrundtief hässlich und dringend davon abzuraten, aber so sollte 
das möglich sein:
1
#include <setjmp.h>
2
3
jmp_buf env;
4
5
int main(void)
6
{
7
   while(1)
8
   {
9
      if (!setjmp(env)) {
10
         funktion1();
11
         funktion2();
12
         funktion3();
13
      }
14
   }
15
}
16
17
ISR(INT1_vect)
18
{
19
   longjmp(env, 1);
20
}

von Karl H. (kbuchegg)


Lesenswert?

setjmp - longjmp

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

von Andreas K. (a-k)


Lesenswert?

Hatte ich vorsichtshalber kontrolliert: SREG wird dabei mit gesichert.

von Oliver (Gast)


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.

von yalu (Gast)


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.

von Peter D. (peda)


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

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.