Forum: Compiler & IDEs Sprung in eine Subroutine von ISR aus!


von Thomas H. (Gast)


Lesenswert?

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...

von m.n. (Gast)


Lesenswert?

Thomas H. schrieb:
> funzt leider nicht...

Du mußt ins Programm einfügen

#define ISR_ENABLE 1

Damit klappt es immer!

von Quack (Gast)


Lesenswert?

Ja das geht. "Funzt leider nicht" ist leider keine brauchbare 
Fehlerbeschreibung.

von Thomas H. (Gast)


Lesenswert?

Quack schrieb:
> Ja das geht. "Funzt leider nicht" ist leider keine brauchbare
> Fehlerbeschreibung.

Wie springt man denn in ein Unterprogramm?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Thomas H. (Gast)


Lesenswert?

1
// Interrupt Service Routine fuer Timer1
2
ISR(TIMER1_OVF_vect) 
3
4
{
5
  TCNT1 = 50000; 
6
  
7
  
8
if ( (!(PIND & (1<<PD1))) || (!(PIND & (1<<PD3))) )
9
{
10
 //Wie springe ich von hier in ein Unterprogramm  
11
}
12
13
else
14
15
{
16
  // tuh was
17
}
18
__________________________________________________ // ISR
19
20
Enter:
21
22
{
23
  
24
PORTD &= ~(1<<PD7);
25
  
26
};

hier soll reingesprungen werden!
_________________________________________________// "Unterprogramm"

von Georg G. (df2au)


Lesenswert?

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?

von Thomas H. (Gast)


Angehängte Dateien:

Lesenswert?

Da kommen komische Fehlermeldungen... habe ich was übersehen?

von Detlef K. (adenin)


Lesenswert?

Zeile 210?
Ach ja, das ist die da.
Na ist doch klar.

von Thomas H. (Gast)


Angehängte Dateien:

Lesenswert?

Detlef Kunz schrieb:
> Zeile 210?
> Ach ja, das ist die da.
> Na ist doch klar.

von Tassilo H. (tassilo_h)


Lesenswert?

Zaehl mal Deine schliessenden Klammern }
Da fehlen ein paar.

von Quack (Gast)


Lesenswert?

Ordentlich einruecken, dann findest du die Klammerfehler automatisch.

Du willst wirklich mit etwas rum spielen, was Akkus laedt? Mit deinen 
Kenntnissen?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Quack (Gast)


Lesenswert?

Ich dachte deine These ist, dass Arduino-Nutzer die duemmsten Fragen 
stellen (was durch diesen Thread auch widerlegt ist).

von Arne (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

Quack schrieb:
> Ich dachte deine These

Ich hab meherer Thesen. Eventuell solle ich mal nach Wittenberg fahren 
und die an irgendwelche Kirchentüren nageln.

von Michael K. (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Quack (Gast)


Lesenswert?

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.

von Michael K. (Gast)


Lesenswert?

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.

von Oliver (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Axel S. (a-za-z0-9)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

Mit Fehlermeldungen per Screendump als JPG sind gleich 3 völlig 
unterschiedliche Fehler friedlich vereint. ;-)

von Mark B. (markbrandis)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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 }?"

von Tassilo H. (tassilo_h)


Lesenswert?

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"

von Programmer (Gast)


Lesenswert?

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. ^^

von sebastan (Gast)


Lesenswert?

> 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.