Forum: Compiler & IDEs Kann ich eine ISR auch wie eine Funktion aufrufen?


von Sam (Gast)


Lesenswert?

Kann ich eine ISR auch wie eine Funktion aufrufen ?

Wenn ja  -  wie geht das ?

Gruß

S.

von Gast (Gast)


Lesenswert?

Evtl. einfach das Interrupt-Flag setzen? Könnte mir vorstellen, das das 
klappt.

von Johannes M. (johnny-m)


Lesenswert?

Von was für einem Controller redest Du? Bei den AVRs kann man Interrupt 
Flags nicht setzen. Und auch ansonsten gilt eigentlich generell, dass 
Interrupt Handler nicht aus dem Programm heraus aufgerufen werden 
können.

von Sam (Gast)


Lesenswert?

Danke Johannes  !

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Vielleicht erzählst du uns ja, was du damit bezwecken wolltest?

von Stefan (Gast)


Lesenswert?

Pack Deine Aufgabe in eine "normale" Funktion, die dann von überall 
aufgerufen werden kann, und setze in Deiner ISR lediglich ein Flag. In 
main() überprüfe das Flag und starte ggf. die Funktion!

von Joerg W. (joergwolfram)


Lesenswert?

Oder rufe in Deiner ISR einfach die benötigte Funktion mit CALL/RCALL... 
auf.
Das mit dem Flag setzen ist nur dann sinnvoll, wenn entweder grosse 
Interrupt-Latenzen nicht stören oder man im Hauptprogramm nix anderes zu 
tun hat als die Flags abzufragen. Aber dann kann man auch gleich 
pollen...

Gruß Jörg

von Stefan (Gast)


Lesenswert?

>Oder rufe in Deiner ISR einfach die benötigte Funktion mit CALL/RCALL...
Kommt auf die Funktion drauf an. Aber generell sollte man eine ISR so 
kurz wie möglich halten. Ein Funktionsaufruf aus einer ISR heraus ist 
i.A. nicht die optimale Lösung!

von Johannes M. (johnny-m)


Lesenswert?

Abgesehen davon, dass man in C Funktionen nicht mit call/rcall aufruft, 
kann ein Funktionsaufruf aus einer ISR heraus durchaus eine Lösung sein. 
Wenn es nur darum geht, Code, der in einer ISR ausgeführt werden soll, 
aus dem laufenden Programm heraus aufzurufen, ohne ihn zweimal schreiben 
zu müssen (einmal in der ISR und nochmal als normale Funktion), dann ist 
es sowieso im Sinne des Programmierers, diesen Code so kurz wie möglich 
zu halten, da er eben in einer ISR ausgeführt werden soll. Und wenn es 
nicht um jeden Prozessortakt geht, also einigermaßen zeitunkritisch ist, 
dann kann man durchaus einen Aufruf einer kleinen Funktion in eine ISR 
packen. Ob es im Einzelfall Sinn macht (vom Compiler erzeugter Overhead 
durch Funktionsaufruf vs. Länge des Codes, der in die Funktion 
reinsoll), muss der Programmierer selbst entscheiden.

von Michael Wilhelm (Gast)


Lesenswert?

Bei den AVRs gibt es da einen Trick. Initialisiere einen externen 
Interrupt z. B. auf High-Flanke, setze den Int-Pin als Ausgang und 
jedesmal beim schreiben des Pins von Low auf High wird ein Interrupt 
ausgelöst.

MW

von Stefan (Gast)


Lesenswert?

>kann ein Funktionsaufruf aus einer ISR heraus durchaus eine Lösung sein.
Das ist schon richtig, kommt aber wie so oft auf den konkreten 
Einzelfall an.
Ohne Sam zu unterstellen, er sei unerfahren - könnte ein Anfänger bei 
einer solchen Aussage auf die Idee kommen, eine ausladenede Funktion zu 
schreiben (womöglich noch mit Delays und Warteschleifen...) und diese 
dann aus Bequemlichkeit auch aus der ISR heraus aufzurufen... was dann 
böse in die Hose gehen kann!
Ich wollte damit nur den Blick dafür schärfen (Oberlehrer :-)), dass 
man ISR's mit Sorgfalt betrachten und programmieren sollte, also kurz 
und bündig :-)

von Johannes M. (johnny-m)


Lesenswert?

Stefan wrote:
> Das ist schon richtig, kommt aber wie so oft auf den konkreten
> Einzelfall an.
Ist alles soweit korrekt. Eben deshalb ja auch meine Anmerkungen 
oben....

Außerdem reden wir ja eigentlich auch schon wieder meilenweit an der 
eigentlichen Fragestellung vorbei. Die lautete nämlich "Kann ich eine 
ISR auch wie eine Funktion aufrufen?" und die Antwort darauf ist ein 
ziemlich klares "Nein" (Siehe Posting von 17.09.2007 17:11). Auf die 
Nachfrage von Jörg hat der OP ja schon nicht mehr reagiert, was 
zumindest darauf hindeutet, dass seine Frage damit beantwortet war...

von Peter D. (peda)


Lesenswert?

Michael Wilhelm wrote:
> Bei den AVRs gibt es da einen Trick. Initialisiere einen externen
> Interrupt z. B. auf High-Flanke, setze den Int-Pin als Ausgang und
> jedesmal beim schreiben des Pins von Low auf High wird ein Interrupt
> ausgelöst.

Ich würd mal vermuten, wenn ich den Pin mit nem Schraubendreher antaste, 
kann ich den Interrupt auch auslösen.


Nimm den besseren Trick:

Der SPM-Interrupt ist in der Applikation vollkommen nutzlos, also ideal 
für solche Spielchen. Sobald freigegeben, wird er gefeuert.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> Und wenn es nicht um jeden Prozessortakt geht, also einigermaßen
> zeitunkritisch ist, dann kann man durchaus einen Aufruf einer kleinen
> Funktion in eine ISR packen.

Das Problem ist, daß das einen großen Overhead zur Folge haben kann, da 
es den Compiler dazu verleitet, am Anfang der ISR jede Menge Register zu 
sichern und am Ende wieder zurückzulesen. Dieer Overhead braucht dann 
unter Umständen mehr Zeit und Flash als die eigentliche Funktion, und 
das ausgerechnet in der ISR, die möglichst kurz sein sollte. In diesem 
Fall würde es sich dann sogar eher lohnen, ein Inlining der Funktion zu 
erzwigen, damit die ISR ihre eigene Kopie davon bekommt.

> Ob es im Einzelfall Sinn macht (vom Compiler erzeugter Overhead
> durch Funktionsaufruf vs. Länge des Codes, der in die Funktion
> reinsoll), muss der Programmierer selbst entscheiden.

Dazu muß er sich aber erstmal im Klaren darüber sein, wie groß dieser 
Overhead tatsächlich ist.

von Uhu U. (uhu)


Lesenswert?

Um die eigentliche Frage zu beantworten:

   Man kann, benötigt dazu aber einen speziellen Mechanismus.

Einige Prozessorfamilien haben dafür sogar einen speziellen Befehl, 
zuweilen heißt der SWI (SoftWareInterrupt).

SWI macht nichts anderes, als ein von der Hardware ausgelöster Interrupt 
auch: Er sperrt die Interrupts, pusht die Rückkehradresse und evtl. das 
Statusregister und lädt dann den PC mit der Startadresse der ISR.

Wenn der Prozessor kein SWI kennt, muß man diese Aktionen nachbilden (in 
ASM-Pseudocode):

     DisableInterrupts
     Push IsrRet
     [Push Status]        // Je nach Prozessor nötig, oder nicht
     Jmp ISR
   IsrRet:

Wichtige Prämisse: Der Prozessorzustand muß am Einsprung der ISR genau 
so aussehen, als wäre Hardwareinterrupt ausgelöst worden.

Solche Geschichten kann man natürlich nur in (inline-)ASM machen.

von Uhu U. (uhu)


Lesenswert?

Nachtrag:
Auf den x86-Prozessoren heißt der Softwareinterrupt-Befehl INT.

Er wird z.B. zum Aufruf von DOS-Funktionen benutzt (INT 20h).

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.