Forum: Mikrocontroller und Digitale Elektronik Funktionsaufruf aus Interrupt


von Johannes (menschenskind)


Lesenswert?

Hallo

Bei mir öffnet ein Interrupt eine Funktion und führt dort eine 
Switch-Case-Anweisung aus, welche auf ein paar Defines aus einer 
Header-Datei zugreift.
Und diese Defines sollen meinen MP3-Player steuern.
Leider klappt das irgendwie gar nicht :(

Beispiel Pause:

switch...
   case 5: Pause();
           break;

in der .h-Datei sieht das so aus:

#define Pause() Control ^= (1<<0)

und dieses Bit wird dann im Hauptprogramm abgefragt mit
while(Control &0x01){}

Control ist bei mir volatile char

Ich las, dass Funktionsaufrufe in ISRn zu vermeiden sind. Aber ich 
wollte einfach mehr Übersicht in meinem Code und hab das deswegen so 
gelöst.
Gebt einfach mal eure Meinungen ab. Ich hab ein dickes Fell :D

Danke

von Peter (Gast)


Lesenswert?

bestimmt fehlt da ein volatile - für mehr raten müssen man den code 
sehen.

von Tim S. (maxxie)


Lesenswert?

Der Interrupt ist nicht zufällig ein Pin-Change Interrupt ohne, dass du 
das Prellen des angeschlossenen Tasters berücksichtigt hast?

Dann wäre die Funktion Pause rein zufällig, je nachdem ob die Taste eine 
gerade/ungerade Anzahl von Prellungen zeigt.

von Blinder (Gast)


Lesenswert?

Ich sehe keinen Funktionsaufruf.

von Johannes (menschenskind)


Lesenswert?

Aber wo sollte denn da ein Volatile fehlen? Die einzige Variable, die da 
ne Rolle spielt ist und bleibt 'Control'.

Die Tasten sind entprellt.

@Blinder: lass dir einfach noch mal den Text vorlesen ;)

von Blinder (Gast)


Lesenswert?

Autsch.

von Tim S. (maxxie)


Lesenswert?

Er hat schon Recht, es existiert in deinem geposteten Code kein 
Funktionsaufruf.

Den Fehler existiert in dem geposteten Code aber auch nicht. Der wird 
wohl an anderer Stelle sein. (Control lokal erneut definiert? Wird die 
case bzw die Bedingung der While nach Eintritt jemeils wieder erreicht? 
etc ...)

von Johannes (menschenskind)


Lesenswert?

Deswegen steht ja auch das Stück Text davor: 
ISR-->Funktionsaufruf-->SwitchCase

Nein, Control wird nach den Defines in der main.c deklariert.

Also müsste es eurer Meinung nach so funktionieren, wie ich es hab?

von Christopher G. (cbg)


Lesenswert?

Johannes Hofmann schrieb:
> Also müsste es eurer Meinung nach so funktionieren, wie ich es hab?

Nein. Unserer Meinung nach solltest du deinen Code posten. Die 
Glaskugeln von heute sind nicht so gut wie sie einmal waren.

von oldmax (Gast)


Lesenswert?

Hi
Wenn ich ISR-Abhängige Funktionsaufrufe habe, dann setze ich mir in der 
ISR ein Flag, welches vom Hauptprogramm bearbeitet wird. Vorteil: Die 
ISR wird nicht durch eine unbekannte Länge einer Funktion belastet und 
kann andere Aufgaben auch noch erfüllen.
Im Hauptprogramm wird dann die eigentliche Funktion bedingt aufgerufen 
und am Schluß das Flag zurückgesetzt.
Z.B. Du hast eine Variable auf 0 solange kein ISR erfolgt ist. Im 
Hauptprogramm fragst du nach ungleich 0 ab und rufst entsprechende 
Unterprogramme auf. Am Ende setzt du die Variable wieder auf 0 und 
kannst auf den nächsten Interrupt warten.
Gruß oldmax

von Tim S. (maxxie)


Lesenswert?

Was Interrupts ad absurdum führt ...

von Falk B. (falk)


Lesenswert?

Siehe Interrupt

von oldmax (Gast)


Lesenswert?

Hi
>Was Interrupts ad absurdum führt ...
Nicht ganz. Angenommen, es kommt ein Byte im USART an und ein Interrupt 
wird ausgelöst. Natürlich lege ich dieses Byte auf den Empfangspuffer 
und passe den Schreibzeiger für diesen Puffer an. Das Hauptprogramm 
erkennt den Unterschied zwischen Schreib- und Lesezeiger und bearbeitet 
den Empfang in den wesentlich aufwändigeren Programmabschnitten. Das mit 
dem Flag sollte lediglich ein Hinweis auf die unbekannte Länge der ISR 
sein. Diese sollte nicht aufwändige Routinen aufrufen, es sei denn, es 
ist wichtig, zeitnah abzuarbeiten. Es gibt auch Kollegen, die qualmen 
ein recht umfangreiches Auswahlprogramm in einen Interrupt und rufen 
dazu noch Unterprogramme in dieser Auswahl auf. In dieser Zeit sind u.U. 
weitere Ereignisse eingetroffen, aber niemand hat sie gehört.....
>Bei mir öffnet ein Interrupt eine Funktion und führt dort eine
>Switch-Case-Anweisung aus, welche auf ein paar Defines aus einer
>Header-Datei zugreift.
und dann das ...
>case 5: Pause();
>           break;

Gruß oldmax

von Reinhard Kern (Gast)


Lesenswert?

oldmax schrieb:
> .... In dieser Zeit sind u.U.
> weitere Ereignisse eingetroffen, aber niemand hat sie gehört.....

Hi,

das ist ja noch einer der einfachsten Fälle, viel schlimmer ist es, wenn 
der nächste Interrupt die aufgerufen Unterprogramme an einer beliebigen 
und wie es der Teufel will ganz ungünstigen Stelle unterbricht. Und 
Variablenzugriffe müssen atomar ausgeführt oder entsprechend abgesichert 
werden - auch wenn man das auf Anhieb nicht sieht, gerade Bitoperationen 
sind z.B. bei vielen Prozessoren keineswegs atomar, sondern werden als 
Read-Modify-Write ausgeführt. Ob sie unterbrechbar sind, müsste man im 
Prozessorhandbuch nachlesen.

In komplexen Systemen (z.B. Windows) wird oft nur ein "Stub"-Programm 
von möglichst wenigen Befehlen als ISR ausgeführt und dann an ein 
normales Programm übergeben - kein Problem, wenn man ein RTOS zur 
Verfügung hat. Wenn nicht, kann man ev. auch dem Prozessor per 
Stackmanipulation ein Unteprogramm unterschieben, aber das ist dann 
schon sehr tricky und hardwarespezifisch.

Gruss Reinhard

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.