Hallo (: Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?!
1 | if ( (!(PIND & (1<<PD1))) || (!(PIND & (1<<PD3))) ) |
2 | {
|
3 | Enter(); |
4 | }
|
5 | |
6 | else
|
7 | |
8 | {
|
9 | // tuh was
|
10 | }
|
funzt leider nicht...
|
|
Forum: Compiler & IDEs Sprung in eine Subroutine von ISR aus!Hallo (: Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?!
funzt leider nicht... Thomas H. schrieb: > funzt leider nicht... Du mußt ins Programm einfügen #define ISR_ENABLE 1 Damit klappt es immer! Ja das geht. "Funzt leider nicht" ist leider keine brauchbare Fehlerbeschreibung. Quack schrieb: > Ja das geht. "Funzt leider nicht" ist leider keine brauchbare > Fehlerbeschreibung. Wie springt man denn in ein Unterprogramm? Thomas H. schrieb: > Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?! Natürlich. Nur mit dem Codefetzen, den du da postest, kann ich persönlich nix anfangen.
hier soll reingesprungen werden! _________________________________________________// "Unterprogramm" genau so, wie du es im ersten Beitrag gemacht hast. Woher weisst du, dass es nicht funktioniert? Weil an PD7 nichts passiert? Könnte es sein, dass deine if-Bedingung nie erfüllt ist? Da kommen komische Fehlermeldungen... habe ich was übersehen? Zaehl mal Deine schliessenden Klammern } Da fehlen ein paar. Ordentlich einruecken, dann findest du die Klammerfehler automatisch. Du willst wirklich mit etwas rum spielen, was Akkus laedt? Mit deinen Kenntnissen? Und wieder ein Beispiel für meine These, dass die mit dem scheuslichsten Code oft die sind, die die dümmsten Fehler im Code haben. Ich dachte deine These ist, dass Arduino-Nutzer die duemmsten Fragen stellen (was durch diesen Thread auch widerlegt ist). Karl Heinz schrieb: > Und wieder ein Beispiel für meine These, dass die mit dem > scheuslichsten > Code oft die sind, die die dümmsten Fehler im Code haben. YMMD! Meine Rede :-) Hatte da schon einige déjà vus. Quack schrieb: > Ich dachte deine These Ich hab meherer Thesen. Eventuell solle ich mal nach Wittenberg fahren und die an irgendwelche Kirchentüren nageln. Karl Heinz schrieb: > Und wieder ein Beispiel für meine These, dass die mit dem scheuslichsten > Code oft die sind, die die dümmsten Fehler im Code haben. Hm, eine These die besagt das die mit den geringsten Programmierkenntnissen die dümmsten Fehler machen. Das ist als ob ich sage: Wer noch wenig kann, der kann noch wenig. In ISRs springt man nicht in 'Unterprogramme' Man setzt ein flag das die ISR aufgerufen wurde. In der Main() wertet man das flag aus und setzt es zurück sobald man den dazugehörigen Code ausführt. Eine ISR ist geeignet das komplette System zu blockieren. Sprünge in der ISR kann man nur erkennen wenn man sich den ISR Code anschaut und das ist sch..sse. Deswegen macht man nur das unbedingst nötigste in der ISR und nicht mehr. Deine 'Unterprogramme' nennt man in C Funktionen. Da man sinnvoller weise jede Programmfunktion in einer 'Funktion' (daher der Name) kapselt stellt sich die Frage nach dem Aufruf von Unterprogrammen nicht. my_function(); ist der Aufruf für eine Funktion der Du keine Daten schickst und die auch keine zurück liefert. Von Globalen Variablen mal abgesehen. C Buch lesen, Funktionen verstehen. Michael Knoelke schrieb: > Karl Heinz schrieb: >> Und wieder ein Beispiel für meine These, dass die mit dem scheuslichsten >> Code oft die sind, die die dümmsten Fehler im Code haben. > > Hm, eine These die besagt das die mit den geringsten > Programmierkenntnissen nicht Programmierkenntnisse. Es gibt durchaus auch Leute, die erst am Anfang ihrer Karriere stehen und daher technisch noch nicht viel wissen, für die es aber trotzdem selbstverständlich ist, Code ordentlich einzurücken und nicht alle Statements an den linken Rand zu quetschen. Für die es selbstverständlich ist, im Code nicht zwischen 2 Anweisungen 30 Leerzeilen reinzuquetschen. Die wenigstens in weiten Teilen ein halbwegs konsistentes Klammernschema haben. usw. usw. Michael Knoelke schrieb: > In ISRs springt man nicht in 'Unterprogramme' > Man setzt ein flag das die ISR aufgerufen wurde. Den schlimmsten Unsinn produziert immer noch der Fortgeschrittene, nicht der Anfaenger. Dein Paradigma ist an dieser Stelle nur irrefuehrend fuer den Frager. Quack schrieb: > Den schlimmsten Unsinn produziert immer noch der Fortgeschrittene, nicht > der Anfaenger. Dein Paradigma ist an dieser Stelle nur irrefuehrend fuer > den Frager. Ist das wirklich so schlimmer Unsinn den ich da verbreite ? Schauen wir uns mal die Originalfrage an: Thomas H. schrieb: > Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?! Meine Antwort sagt: Möglich ja, aber unsauber. Wenn das irreführend für jemanden ist der gerade vom Moderator wegen seines Code Wirrwarrs abgebügelt wird dann heuchel ich jetzt natürlich pflichtschuldig Betroffenheit. Michael Knoelke schrieb: > Thomas H. schrieb: >> Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?! > > Meine Antwort sagt: Möglich ja, aber unsauber. Die Antwort ist natürlich genauso unsauber. Ja, man kann "Subroutinen" aus einer ISR aufrufen. Punkt. Ob das jetzt unsauber, nicht zu empfehlen, oder ganz prima ist, hängt vom Programmaufbau ab. Wie bei eigentlich allem, besonders in der MC-Programmierung, muß man nur wissen, was man da tut. Oliver Oliver schrieb: > vom Programmaufbau ab. Wie bei eigentlich allem, besonders in der > MC-Programmierung, muß man nur wissen, was man da tut. Und genau da liegt beim TO das Problem. Wenn man ihm jetzt auch noch naheliegt, dass er den Funktionsaufruf aus Performance Gründen nicht machen soll, dann handelt er sich mehr Ärger ein, als wie wenn alle paar Millisekunden mal in der ISR ein paar Register zuviel gesichert und wieder hergestellt werden. Denn: Performance ist in seinem Programm das geringste aller Probleme. Ich würde das so sehen: Technisch gesehen hat Michael recht. Unter Berücksichtigung des Levels, auf dem der TO momentan operiert, ist es aber ein paar Monate zu früh, auf dieses Detail einzugehen. Zumal es in diesem Programm auch in der Zukunft sicher nicht zum Problem wird. Michael Knoelke schrieb: > Quack schrieb: >> Den schlimmsten Unsinn produziert immer noch der Fortgeschrittene, nicht >> der Anfaenger. Dein Paradigma ist an dieser Stelle nur irrefuehrend fuer >> den Frager. > > Ist das wirklich so schlimmer Unsinn den ich da verbreite ? Niemand hat gesagt daß du Unsinn verbreitest. Nur daß du dem Frager nicht hilfst. > Schauen wir uns mal die Originalfrage an: > > Thomas H. schrieb: >> Ist es möglich aus einer ISR herraus in eine Subroutine zu springen ?! > > Meine Antwort sagt: Möglich ja, aber unsauber. Nein, das sagt sie nicht. Und tatsächlich ist die Aussage in dieser Generalität Unsinn. Denn es ist ganz normal und möglicherweise sogar sehr guter Stil, Funktionen aus einer ISR aufzurufen. Beispiel: ein Programm mit mehreren Modulen, die jeweils eine Funktion haben die zyklich aufgerufen werden muß. Noch konkreter: ein Gerät das per IRMP ein Fernbediensignal auswertet und ein paar lokale Encoder und Tasten abfragt. Dann ist es ganz normal, diese Funktionen aus ein- und derselben Timer-ISR aufzurufen. Andererseits scheint es, als wäre das "Unterprogramm" des TE ein einzelnes C-Statement. Das wird der Compiler ohnehin inlinen. Jegliche Optimierung auf der C-Code Seite wäre hier rausgeworfen. Erst recht, wenn der TE dadurch dann (noch) länger braucht, um überhaupt erstmal korrekten Code zu schreiben. XL Mit Fehlermeldungen per Screendump als JPG sind gleich 3 völlig unterschiedliche Fehler friedlich vereint. ;-) In diesem Zusammenhang sei mir eine Frage gestattet. Warum zählt ein handelsüblicher C-Compiler nicht für ein einzelnes Modul, wie viele öffnende und wie viele schließende Klammern er im Quelltext vorfindet? Das sollte doch eigentlich nicht so schwer sein. Und würde womöglich zu besseren, sinnvolleren Fehlermeldungen führen. Wir alle kennen ja diese Bildschirmseiten voll mit Meldungen vom Compiler, weil ein einzelnes } oder ; oder ) fehlt... Ich bilde mir ein, Clang/LLVM macht das besser, bin mir aber nicht sicher. Mark Brandis schrieb: > In diesem Zusammenhang sei mir eine Frage gestattet. > > Warum zählt ein handelsüblicher C-Compiler nicht für ein einzelnes > Modul, wie viele öffnende und wie viele schließende Klammern er im > Quelltext vorfindet? Das tut er im Prinzip ja. Durch die Grammatik hat er diese implizite Zählung. > Das sollte doch eigentlich nicht so schwer sein. > Und würde womöglich zu besseren, sinnvolleren Fehlermeldungen führen. Warum sollte es? > Wir alle kennen ja diese Bildschirmseiten voll mit Meldungen vom > Compiler, weil ein einzelnes } oder ; oder ) fehlt... Das Problem ist, dass die Dinge nicht eindeutig sind. Der Compiler hat sein Regelsystem und er versucht den vorgegebenen Text auf diesem Regelsystem abzubilden. Sobald aber der erste Fehler vorliegt (der meistens auch ganz gut diagnostiziert wird), passt hinten und vorne nichts mehr. Teil des Problems ist es zb auch, dass der Compiler ja keine logische Analyse macht, ob das ganze auch Sinn ergibt. Vergisst du mitten in einer Funktion eine schliessende }, dann wird ab dieser Stelle alles weitere falsch zugeordnet. Irgendwann kommt der Compiler dann zb drauf, dass du versuchst innerhalb einer Funktion eine weitere Funktion zu definieren. Laut C Regeln ist das nicht erlaubt. Die Fehlermeldung des Compilers muss dann lauten "Attempt do define a function inside another function." Schon. Aber der eigentliche Fehler ist ein ganz anderer. Der eigentliche Fehler besteht darin, dass irgendwo vorher eine schliessende Klammer vergessen wurde. Das muss aber nicht die letzte der Klammern sein, die die Funktion beendet. Das kann auch die vergessene Klammer beim if von vor 50 Zeilen gewesen sein. Fehler zu detektieren, sinnvolle Fehlermeldungen auszugeben und, auch wichtig, zu versuchen nach dem ersten Fehler sich zumindest soweit wieder in der Grammatik auf einen möglichen Wiederaufsetzpunkt vorzutaste, dass weitercompiliert werden kann, das gehört zu den schwierigen Dingen im Compilerbau. (Weitercompilieren möchte man in der Hoffnung, dass man zumindest soweit wieder neu aufsetzen kann, dass man im selben Compilerlauf noch weitere Fehler diagnostizieren kann) Übrigens: die Fehlermeldung muss auch nicht "attempt to define function inside function" lauten. Dann das Problem besteht darin, dass der Compiler an dieser Stelle überhaupt nicht rausfinden muss, dass es sich hier um den Funktionskopf einer neuen Funktion handelt. Für ihn sieht die Sache ganz anders aus. Für ihn stellt sich die Frage: Was ist innerhaln einer Funktion grammatikmässig erlaubt, was ist laut Grammatik überhaupt möglich. Und dann trifft er auf ein Zeichen, das nicht möglich ist, eines das laut Grammatik an dieser Stelle gar nicht auftreten darf. So, worin besteht da jetzt der Fehler? Was war der Auslöser? Das alles weiß der Compiler nicht und das ergibt sich auch nicht aus der Grammatik. Alles was er feststellen kann ist: der Text, den ich da habe, das nächste Token, das passt auf keines der erlaubten Fortsetzungen. OK, im Laufe der Zeit haben die Compilerbauer natürlich gelernt, das etwas was zunächst wie ein Funktionsprotoyp innerhalb einer Funktion aussieht und dann doch nicht mit einem ';' abgeschlossen ist, sondern mit einem '{' weitergeht, im Regelfall der Versuch einer Funktionsdefinition innerhalb einer Funktionsdefinition ist und das dies meist darauf zurückzuführen ist, das vorher ein } vergessen wurde. Die Fehlermeldung lautet dann "Attempt to define function inside function. Did you miss a previous }?" Natuerlich muss man daran denken, dass "nested functions" eine GNU C-Erweiterung sind und daher erstmal keinen Fehler darstellen. Eine Funktionsdefinition kann ueberall stehen, wo auch eine Variablendefinition erlaubt ist. Also ist die Fehlermeldung aus dem Screenshot die einzig sinnvolle: "Hier muss doch noch ne Anweisung kommen, die aktuelle Funktion ist ja noch gar nicht fertig, aber die Quelldatei ist zuende" Michael Knoelke schrieb: > In ISRs springt man nicht in 'Unterprogramme' > Man setzt ein flag das die ISR aufgerufen wurde. > In der Main() wertet man das flag aus und setzt es zurück sobald man den > dazugehörigen Code ausführt. Man springt in ner ISR auf jeden Fall in Funktionen hinein, um sequenziel was abzuarbeiten. Ansonsten ist das Progrämmchen recht klein oder man macht grundsätzlich was falsch. ^^ > Enter: > > { > > PORTD &= ~(1<<PD7); > > }; > > hier soll reingesprungen werden! Wenn du mit "Unterprogramm" ein Label meinst, dann springt man da mit goto hin. Aber bist du sicher, dass du das willst? 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.
|
|