Funktionsaufruf aus Interrupt

OP #1558857
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
#1558880
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 ...)
Gast #1558921
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
Gast #1559018
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
Gast #1559163
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren