www.mikrocontroller.net

Forum: Compiler & IDEs Unterprogramm abbrechen


Autor: Dario C. (dario) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammmen,

irgendwie komme bei folgendem Problem ich nicht weiter:

Ich habe eine LED Lauflichtsteuerung. Die basiert auf vielen 
Unterprogrammmen, die jeweils ein Muster erzeugen und jeweils zwischen 
10 Sekunden und 10 Minuten laufen.

Jetzt habe ich Interruptgesteuert per Infrarot eine Empfangsroutine, die 
einen RC5-Code empfängt. Der Code soll gleich die Programmnummer sein.

In der Main sähe das dann so aus:
    while(1){
        if (prog == 1){
       snake();
        }
        if (prog == 2){
       schach();
        }
        if (prog == 3){
       laufschrift();
        }
    }

Mein Problem: Die IRQ speichert nach Empfang eines Codes diesen in 
"prog", aber das aktuelle Programm läuft ja noch.

Wie stelle ich es jetzt elegant an, dass die Unterprogramme abgebrochen 
werden, wenn ein neuer Code empffangen wurde?

Zur Zeit habe ich das wie folgt gelöst: Jedes Unterprogramm ruft immer 
die selben Funktionen (Delay und Framebuffer-Ausgabe) auf. Im Moment 
habe ich diese beiden Funktionen so gepatcht, dass Delay nach einem 
empfangenen Zeichen kein Delay macht und die Ausgabefunktion keine 
Ausgabe macht, aber die Unterprogramme laufen noch komplett durch, nur 
schneller.

Das muss doch irgendwie eleganter gehen, oder?

Hat hier jemand einen Tip für mich?

Autor: Marius Wensing (mw1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Setze halt ein "Kill"-Flag, das die Unterprogramme regelmäßig prüfen. 
Wenn das Flag gesetzt ist, soll sich das Unterprogramm so schnell wie 
möglich beenden.

MfG
Marius

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du solltest das anders organisieren.

das main sollte etwa so aussehen:
while(1)
{

  switch (prog)
  {
  case 1:
    snake();
    break;
  case 2:
    schach();
    break;
  }

}



Dein IR-COde schreibt das aktuelle Programm in prog und ruft das 
permanent auf. Du musst die Lauflicht-funktionen so programmieren, dass 
diese immer nur durchlaufen und beendet werden können. 
(Zustandsautomaten verwenden!)

Autor: Dario C. (dario) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

@Matthias:
>   switch (prog)
>   {
>   case 1:
>     snake();
>     break;
>   case 2:
>     schach();
>     break;
>   }

Naja, das behebt nicht das problem und technisch ist das kein großer 
Unterschied.

> Dein IR-COde schreibt das aktuelle Programm in prog und ruft das
> permanent auf. Du musst die Lauflicht-funktionen so programmieren, dass
> diese immer nur durchlaufen und beendet werden können.
> (Zustandsautomaten verwenden!)

Toll, so habe ich das im Prinzip ja auch, aber ich hatte mal irgendwo 
was gelesen, wo jemand das mit sowas wie LONGJUMP oder so versucht hat.

Alternativ könnte man auch ein OS einsetzen und die einzelnen Tasks 
einfach abschießen, aber ob das nicht wie mit Kanonen auf Spatzen 
schießen ist weiß ich nicht.

Deswegen: Weiß jemand wie man in diesem Zusammenhang LONGJUMP einsetzen 
kann?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
longjmp würde ich nicht einsetzen, das wär mir zu viel Hack ;-) vor 
allem aus einer ISR heraus...

In meiner Scope-Clock habe ich ein ähnliches Problem: einerseits gibt es 
komplexe Darstellungsroutinen (Snake, Asteroids, ...) andererseits muss 
auf Eingaben reagiert werden und in genau festgelegten Zeitabständen der 
Elektronenstrahl positioniert werden.

Das hab ich so gelöst, daß das Zeichnen in einer ISR stattfindet. Die 
Vorberechnungen hingegen geschehen im Hauptprogramm in 
nichtblockierenden Routinen. Wenn du irgendwo delay-Geraffel 
verwendest oder auf Timer wartest, hast du schon verloren.

Im Hauptprogramm gibt es Handler für die verschiedenen Menüpunkte 
(Spiele, etc.) mit Routinen die zB einen neuen Frame berechnen. Die 
Darstellung bzw. Interpretation geschieht jedoch in einer ISR.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dario C. schrieb:

> Deswegen: Weiß jemand wie man in diesem Zusammenhang LONGJUMP einsetzen
> kann?

Das willst du eigentlich nicht wirklich.

Für dein Problem gibt es 2 Lösungsansätze

Der eine ist der pragmatische, den man bei dir jetzt zum Einsatz bringen 
kann, weil der Rest schon fertig ist.

Der andere ist der, den du von vorne herein hättest gehen sollen.


Der pragamtische geht so:
Jedes deiner Unterprogramme prüft in regelmässigen Zewitabständen ob die 
'Abbruch-Variable' gesetzt wurde und kehrt ins Hauptprogramm zurück.

Der andere Weg besteht darin, dass ein Muster nicht ein einziges 
'komplexes' UNterprogramm ist sondern, dass im Hauptprogramm nach 
jeweils x Millisekunden dem gerade aktiven Muster die Chance gegeben 
wird, einen 'Musterschritt' zu machen. Danach muss das jeweilige 
Unterprogramm sofort zurückehren und die Kontrolle so wieder abgeben.
Eine bewährte Organisationsform wurde weiter oben schon genannt: Ein 
Zustandsautomat.

Eine andere Möglichkeit besteht darin, einen Weg zu suchen, wie man 
jedes Muster einfach nur durch Daten beschreiben kann, der 
Ausführungsteil, der das Muster aus diesen Daten dann letztendlich 
erzeugt, aber immer derselbe ist.
Sprich: Ein einziger Programmcode erzeugt nur durch Austausch von Daten 
(zb in einzelnen Arrays) die verschiedenen Muster.

Autor: sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte man nicht aus der ISR einen REset ausführen und beim Neustart 
'prog' (darf natürlich nicht überschrieben werden bei der 
Initialisierung) auswerten ?

Autor: Qwertz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Könnte man nicht aus der ISR einen REset ausführen und beim Neustart
>'prog' (darf natürlich nicht überschrieben werden bei der
>Initialisierung) auswerten ?

Könnte man. Ist aber völlig unnötig wenn man es "richtig" macht, d.h. so 
wie Karl Heinz es beschrieben hat.

Autor: Dario C. (dario) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, dann lasse ich es also alles so wie es ist.

- In den Unterprogrammen wird regelmäßig ein KILL-FLAG ausgewertet und
  wenn gesetzt das Unterprogramm abgebrochen.
- Die Ausgaberoutinen geben nix aus, wenn das KILL-FLAG gesetzt ist.
- Die Delay-Funktion mach kein delay mehr, wenn das KILL-FLAG gesetzt 
ist.

Nicht sexy, aber funktioniert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.