Hallo,
ich möchte aus 2-3 Interrupts heraus die gleiche Funktion aufrufen.
Nicht gleichzeitig, es geschieht immer an anderen Zeitpunkten.
Ist dies möglich?
Ich muss ja für die Interrupts volatile Variablen deklarieren.
kann man diese Werte dann auch einfach im Interrupt übergeben?
Also ungefähr so:
Aufruf in ISR
Das klingt für mich jetzt schon nach falscher Nutzung der Interrupts.
Setze ein Flag und mache den Aufruf deiner Funktion per Polling auf das
Flag. das Flag kannst du in jeder deiner ISR setzen.
MFG
Grundsätzlich: Man kann innerhalb einer Unterbrechung machen, was man
will.
Ob das immer sinnvoll ist und ohne Einfluss auf andere Funktionen ist
eine ganz andere Sache.
Man sollte aber nie den zeitlichen Aspekt aus den Augen verlieren. Auch
die Problematik des Zugriffs, von mehreren Stellen aus, auf die gleichen
Variablen, lässt sich nicht nur auf: Definieren wie sie einfach als
"volatile" reduzieren.
Was machst Du eigentlich, wenn die Funktion mehrfach, gleichzeitig
aufgerufen wird?
Oder sind deine Unterbrechungen so nett nicht gleichzeitig aufzutreten?
NurEInGast schrieb:> Wen stört es wenn die Funktion mehrfach aufgerüfen würde ?> Variablen auf dem Stack - Ich verstehe das Problem nicht ?
es gibt kein Problem.
maximal das der ISR zu langsam wird, weil sobal andere funktionen
aufgerufen werden alle Register gesichert werden müssen.
Die funktionen sollte aber selber "reentrant" programmiert sein.
http://de.wikipedia.org/wiki/Eintrittsinvarianz
@NurEInGast
Wenn für Dich der mehrfache Aufruf einer Funktion in die Rubrik: "Kein
Problem" gehört, wirst Du wahrscheinlich auch nie Probleme damit
bekommen.
Da hier von Unterbrechungen die Rede ist, kannst Du Dir wahrscheinlich
auch vorstellen, dass der wiederholte Aufruf vor dem Abschluss des
Vorherigen gemeint ist.
Ich zumindest finde, das solche Probleme, ein wenig Grübelei wert sind.
amateur schrieb:> Wenn für Dich der mehrfache Aufruf einer Funktion in die Rubrik: "Kein> Problem" gehört, wirst Du wahrscheinlich auch nie Probleme damit> bekommen.
warum sollte das ein Problem sein? Sotwas ist doch der Normalfall. Aus
dem grund sollte eine funktion ja auch reentrant sein.
Probleme gibt es nur bei funktion die es nicht sind, und das sollte wo
wenig wie möglich sein.
amateur schrieb:> ein wenig Grübelei wert sind.
Darüber nachdenken und wissen was man tut ist immer gut.
Aber wer schon mal was von reentrance gehört hat, der darf natürliche
funktionen aus der ISR aufrufen.
Und in der Funktion die der ledfreund angegeben hat ist kein Pointer
übergeben, keine globalben variable genutzt ........
Du hast recht - man muss wissen was man tut.
Es erschien in den vorherigen Postings nur so als ob aufruf einer
Funktion aus der ISR was besonderes, gar seltsames oder fürchterlich
gefährliches währe. Und das ist es nicht - wenn man weis was man tut !
Da hier keine Controllerfamilie genannt wurde, unterstelle ich mal, daß
es sich hier um AVRs handelt.
amateur schrieb:> Was machst Du eigentlich, wenn die Funktion mehrfach, gleichzeitig> aufgerufen wird?
Wird sie das denn? Von wem denn? Ein mehrfacher Aufruf einer Funktion
kann aus sich selbst heraus erfolgen oder wenn sie sowohl im
Hauptprogramm oder einer seiner Verzweigungen als auch in einer ISR
aufgerufen werden kann.
amateur schrieb:> Oder sind deine Unterbrechungen so nett nicht gleichzeitig aufzutreten?
Das ist vollkommen egal. Entscheidend ist, wann sie abgearbeitet werden.
Und das geht beim AVR immer schön der Reihe nach.
Auch bei anderen Controllern mit Prioritätssteuerung werden sie das,
solange die Priorität gleich ist.
Womit dieses Problem überhaupt nicht auftreten kann:
amateur schrieb:> Man sollte aber nie den zeitlichen Aspekt aus den Augen verlieren. Auch> die Problematik des Zugriffs, von mehreren Stellen aus, auf die gleichen> Variablen, lässt sich nicht nur auf: Definieren wie sie einfach als> "volatile" reduzieren.
Das Problem des Zugriffs auf eine Variable von mehreren Stellen entsteht
nur dann, wenn die Funktion im Hauptprogramm abgearbeitet wird, die
Variablen aber in mehreren ISRs verändert werden können und die
Variablenbehandlung in der Funktion nicht atomar erfolgt. Wobei dann
eine atomare Abarbeitung erst wieder für Timigprobleme sorgen kann. Weil
jetzt nicht nur die anderen Interrupts die Ausführung einer ISR
verzögern können, sondern auch das Hauptprogramm.
Bei der Abarbeitung der Funktion in einer ISR treten all diese Probleme
gar nicht erst auf.
Die Funktion kann selbstvertständlich in einer ISR ausgeführt werden.
Irgendwo muss man sie ja abarbeiten. Daß die Zeit dafür so kurz sein
muß, daß die anderen Funktionsaufrufe dadurch nicht beeinträchtigt
werden und die aktuelle ISR in jedem Fall fertig sein muß, bevor ein
erneuter Aufruf erfolgt, sollte dabei klar sein. Aber selbst wenn das
auftritt hat das allenfalls eine unerwartete Programmausführung zur
Folge, z.B. daß beim Multiplexen die LEDs nicht gleichmässig leuchten
oder der UART ein Byte verschluckt.
Stacküberläufe und damit verbundene Abstürze kann es dabei nicht geben,
da auch dieser IRQ die laufende ISR nicht unterbrechen kann.
Nicht das ewig heruntergebetete "So schnell wie möglich" sondern "So
schnell wie nötig" ist das Ziel. Wenn das nicht passt, ist das Timing an
sich das Problem.
Dieses Timingproblem hätte man aber in verschärfter Form auch bei der
"Flaglösung" wodurch die Probleme erst geschaffen werden.
Dauert das Abarbeiten einer Funktion allerdings länger als ein
ISR-Interval, muß diese in der Hauptschleife aufgerufen werden. Dann
sollte allerdings das Flag setzen und damit der Funktionsaufruf, erst
erfolgen wenn die Funktion fertig. Sollte das Flag vorher gesetzt werden
kann es aber auch hierbei nicht zu einem mehrfachen Aufruf der Funktion
kommen.
Aber dann ist wieder das gesamte Timing eher fragwürdig.
NurEinGast schrieb:> Darüber nachdenken und wissen was man tut ist immer gut.> Aber wer schon mal was von reentrance gehört hat, der darf natürliche> funktionen aus der ISR aufrufen.> Und in der Funktion die der ledfreund angegeben hat ist kein Pointer> übergeben, keine globalben variable genutzt ........> Du hast recht - man muss wissen was man tut.
Natürlich muss man wissen, was man tut. Aber man sollte auch die
richtigen Schlüsse daraus ziehen.
mfg.
Peter II schrieb:> Die funktionen sollte aber selber "reentrant" programmiert sein.
Das sind in der Regel nur Funktionen, die etwas berechnen und keine
statischen Variablen anlegen.
Funktionen, die IO-Ressourcen benutzen (Ports, Timer, UART, SPI, LCD
usw.) sind es oft nicht.
Einen schönen Zeichensalat gibt es z.B., wenn Main und Interrupt
gleichzeitig auf ein LCD zu schreiben versuchen.
Eine weitere Fallgrube sind Funktionen mit atomaren Abschnitten. Diese
müssen dann den Interruptstatus sichern und restoren.
Peter Dannegger schrieb:> Eine weitere Fallgrube sind Funktionen mit atomaren Abschnitten. Diese> müssen dann den Interruptstatus sichern und restoren.
Nicht solange sie nur in ISRs aufgerufen werden und nicht schachteln.
Thomas Eckmann schrieb:> daß es sich hier um AVRs handelt.AVR höchstwahrscheinlich, sind noch nicht ganz schlüssig.
Das Timing ist erstmal egal, ging mir darum, ob es generell möglich ist.
Aber wie ich sehe, sollte dies erstmal kein Problem sein.
Danke erstmal für die zahlreichen Antworten!
ledfreund schrieb:> Das Timing ist erstmal egal, ging mir darum, ob es generell möglich ist.
Ich denke nicht das das "Timing" egal ist, wenn Du z.B. ein Lauflicht
implementierst und das auf verschiedene Flanken reagieren soll kann es
passieren das es nicht läuft sondern sporadisch an ist usw. usf.
> Aber wie ich sehe, sollte dies erstmal kein Problem sein.
Solange wir nicht wissen was die Funktion tun soll und ob es
Abhängigkeiten gibt kann Dir das niemand beantworten.
Im Fall der Fälle kann der Compiler auch der Meinung sein die Funktion
jeweils direkt in der ISR unterzubringen.
Die Version mit globalem volatile Flag ist vorzuziehen.