Kann ich eine ISR auch wie eine Funktion aufrufen ? Wenn ja - wie geht das ? Gruß S.
Evtl. einfach das Interrupt-Flag setzen? Könnte mir vorstellen, das das klappt.
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.
Vielleicht erzählst du uns ja, was du damit bezwecken wolltest?
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!
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
>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!
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.
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
>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 :-)
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...
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
> 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.