- 12V Akku mit 280 Ah bauen         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 22

Thema: Verlassen einer Funktion um später zurück zu springen.

  1. #11
    Erfahrener Benutzer Roboter-Spezialist Avatar von witkatz
    Registriert seit
    24.05.2006
    Ort
    NRW
    Alter
    53
    Beiträge
    540
    Blog-Einträge
    17
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von Iqon Beitrag anzeigen
    ob man das ganze Switch-Case gedöns irgendwie Sinnvoll verstecken könnte.
    Verstecken kann man in C fast alles. Ob es sinnvoll ist, ist eine andere Frage. Wäre zwar nicht meine Art, aber bitte schön, ein Q&D Vorschlag zum Verstecken von "Switch-Case-Gedöns":
    Code:
    #include "StateMachine.h"
    void longrunning(void) {
        STATEMACHINE_INIT 
            ;/*...*/ // do something
            step++;
    
        STATEMACHINE_STEP(1)       
            ;/*...*/ // do something more
            step++;
    
        STATEMACHINE_STEP(2)
            ; // do even more
            if(error) 
                step = -1;
            else
                step = 0;
    
        STATEMACHINE_STEP(-1)
            ; // do some error handling
            step = 0;
    
        STATEMACHINE_END
    }
    Nachtrag:
    Ich hab die quick'n'dirty Macros etwas überarbeitet und mittlerweile gefällt mir die Lösung sogar
    Angehängte Dateien Angehängte Dateien
    Geändert von witkatz (17.09.2015 um 22:51 Uhr) Grund: Angehängte Headerdatei im eigenen PIC Projekt getestet und korrigiert

  2. #12
    Neuer Benutzer Öfters hier
    Registriert seit
    24.05.2012
    Beiträge
    14
    Zitat Zitat von witkatz Beitrag anzeigen
    Verstecken kann man in C fast alles.
    Das stimmt natürlich, ob das immer sinnvoll ist, ist die andere Frage Danke für eure Hilfe.

    Ich denke die Switch-Case (ohne Macros) Variante ist die einfachste und damit beste. Also getreu dem KISS Motto, bleibt es bei dieser Variante.

  3. #13
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    55
    Beiträge
    2.814
    Wenn ich das richtig verstehe, willst Du eigentlich ein Multitasking realisieren.
    Task 1 ist dein Longrunning Prozess Task 2 alles andere.

    Man müsste mal prüfen ob sich das mit einer Timer IRQ Routine realisieren lässt.
    Das wäre die einzige Möglichkeit sicherzustellen, das der Longrunning Task sicher nach einer gewissen Zeit unterbrochen wird und in den andern Task zurückgekehrt wird.

    Da ja normalerweise die IRQ Routine komplett abgearbeitet wird, bevor in das unterbrochene Programm zurückgekehrt wird, sollte entweder die Hauptschleife die IRQ Routine sein und nach einem Durchlauf in den Longrunning Prozess zurückkehren oder du befasst dich mal damit was Linus Torvalds als ersten Teil von Linux realisiert hat (Ein präemptives Multitasking das zwichen zwei Tasks hin und her springt und dabei die Rettung aller Register, Pointer und des Stacks übernimmt). Was du versuchst ist ein kooperatives Multitaksing, damit ist Microsoft schon bei Windows 1 bis 3 gescheitert. Bleibt ein Task hängen ohne das ein Reset verursacht wird, fällt das ganze wie ein Kartenhaus in sich zusammen.

    Wie so was geht steht z.B. hier:
    http://www.gbv.de/dms/ilmenau/toc/592544346.PDF
    oder hier:
    Multitasking mit AVR RISC-Controllern
    Prof. Dr. Ernst Forgber
    Franzis Verlag
    Leseprobe:
    http://www.ciando.com/img/books/extr...5270558_lp.pdf

    Multitasking für AVR:
    http://www.controllersandpcs.de/pdfs/vmavr.pdf

    https://xivilization.net/~marek/bina...ltitasking.pdf

    http://www.wseas.us/e-library/conferences/2015/Dubai/CEA/CEA-24.pdf

    http://www.ripublication.com/irph/ij...4n17spl_16.pdf

    http://www.ijert.org/view-pdf/7712/r...icrocontroller

    http://citeseerx.ist.psu.edu/viewdoc...=rep1&type=pdf
    Geändert von i_make_it (17.09.2015 um 12:24 Uhr)

  4. #14
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Der TE wollte kein OS...

    Mit so einer State Machine kann man so einiges erreichen, denke auch das es die ideale Lösung ist. Hatte auch mal so eine Aufgabe, eine leere State Machine, ca 5000 ? wie das gehen soll, dann die Erleuchtung und Erkenntnis das man damit einem Mikrokontroller super auslasten kann ohne das eine einzelne lange Berechnung alles blockiert.
    Sozusagen Multitasking light.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #15
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    55
    Beiträge
    2.814
    Multitasking und Betriebssysteme (OS) sind auch zwei verschiedene Sachen. Ein Multitasking bedingt noch kein Betriebssystem und Betriebsysteme müssen nicht zwingend Multitasking tauglich sein.
    Eine State Machine (endlicher Automat) ist eine Form kooperatives Multitasking zu realisieren und kein "Multitasking light".
    Der Nachteil ist halt wenn ein Task nicht kooperiert (Fehlerfall) dann gibt es einen Systemabsturz.
    Präemptives Multitasking hat halt n+1 Tasks (der eine Task ist der Multitasking Task)
    Der Multitasking Task steuert stur seine Zeitscheibe, unabhängig davon ob ein Task abgestürzt ist oder nicht.
    Man könnte sogar über Status Informationen eine Überwachung des Laufverhalten der anderen Tasks realisieren und so einen abgestürzten Task nach maximal 3 Durchläufen der Zeitscheibe terminieren und ggf. neu starten.
    Kooperatives Multitasking funktioniert solange alles fehlerfrei läuft.
    Präemptives Multitasking kapselt die einzelnen Tasks und verhindert so ein Versagen des gesamten Systems wenn ein Einzeltask versagt.
    Eine Selbstheilung des Gesamtsystems erfordert neben dem präemptiven Multitasking zusätzlich eine FST die die Zustände jeden Tasks überwacht und beim Verharren in einem Zustand entsprechende Masnahmen veranlasst.

    Es kommt halt darauf an wie wichtig einem das korrekte Weiterlaufen bstimmter Tasks ist, bzw. welche Folgen das nicht korrekte arbeiten derselben hat, um zu entscheiden welche Form des Multitaskings man implementieren will.

    Bei Servoreglern, geht man z.B. so weit das Motorstrom Regelung und Motorstrom Überwachung sogar in echtzeit parallel auf verschiedener Hardware laufen, da die Folge einer zu langsamen Motorstrom Überwachung, bei zu langem Überstrom, die Zerstörung des Reglers und des Motors zur Folge haben kann. Und in Folge die Beschädigung oder Zerstörung der Hardware die an dem Motor hängt (inklusive Personenschäden).
    Geändert von i_make_it (18.09.2015 um 12:16 Uhr)

  6. #16
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von i_make_it Beitrag anzeigen
    Eine State Machine (endlicher Automat) ist eine Form kooperatives Multitasking zu realisieren und kein "Multitasking light".
    Der Nachteil ist halt wenn ein Task nicht kooperiert (Fehlerfall) dann gibt es einen Systemabsturz.
    In einigen Sprachen werden solche State Machines auch automatisch vom Compiler erzeugt, z.B. bei Verwendung von async und await in C#. Das erspart einiges an Schreibarbeit und umgeht einige Fehlerfälle. Für einen zukünftigen C++ Standard ist das zumindest vorgeschlagen, einige Compiler (z.B. Visual C++ 2015) bieten schon experimentelle Unterstützung (mit __yield, __async und __await).

  7. #17
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    866
    Hier (http://www.mikrocontroller.net/articles/Multitasking) steht einiges über kooperatives und präemptives Multitasking.
    Allerdings steht auch drin, dass beim präemptivem Multitasking neben den Registern auch der Stack für jede Task umgebogen werden muss (das ist eigentlich auch logisch, wenn man weiß, dass bei einem Funktionsaufruf in einer Task Übergabeparameter und Rückgabewerte über den Stack transferiert werden). Das wird bei Controllern mit wenig RAM relativ schnell eng, insbesondere, wenn weitere ISRs auch noch ihre Register auf den Stack der aktuellen Task poppen wollen).

    Alternativ zur Switch-Anweisung: Mehrere kleine Funktionen schreiben, statt der Step-Variable und dem Switch den Funktionszeiger für die "Task" in der Jobliste jeweils aus einer Funktion heraus auf die nächste Funktion schieben.
    Geändert von Holomino (19.09.2015 um 10:45 Uhr)

  8. #18
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2005
    Alter
    70
    Beiträge
    157
    Moin,

    manche C-Versionen (z.B. c#) bieten die Funktion yield, die so etwas kann. Für c habe ich dies gefunden: http://stackoverflow.com/questions/1...ing-yield-in-c

    Wenn ich das Problem richtig verstehe liegt folgende Situation vor:

    1) Es gibt eine Liste von Aufgaben, die in einer bestimmten Reihenfolge abgearbeitet werden sollen (Jobstack).
    2) Hin und wieder sollen bestimmte Aufgaben erledigt werden, dies aber auch während ein Job aus 1) ausgeführt wird.

    Lösen kann man das Problem, indem man 1) und 2) nicht in einer gemeinsamen Funktion implementiert (z.B. in main()):

    Preemptives Verhalten: Man packt 2) in eine Timer-ISR. Dann geschieht die Ausführung regelmäßig. Führt man die ISR als non-blocking Version aus, werden andere Interrupts nicht behindert. Dann wird 2) regelmäßig ausgeführt, ohne dass sich die Jobs darum kümmern müssten. main() würde sich dann nur noch darum kümmern, dass nach Beendigung eines Jobs der nächste gestartet würde. Ist die Aufgabe länger als die Timer-Periode, muss man den Timer zu Beginn der ISR stoppen und am Schluss wieder starten.

    Kooperatives Verhalten: Man packt 2) in eine Routine und ruft diese in den gewünschten Stellen in den Jobs aus. Auch hier übernimmt main() die Verwaltung der Jobs. Diese sähe etwa so aus (Pseudo-Code):
    Code:
    main()
    { while(true)
        StarteNaechstenJob();
    }
    
    TueWasManNichtLassenKann()
    { // Der Name sagt alles ..
    }
    
    Job1()
    { ... // erster Teil der Arbeit von Job1
      TueWasManNichtLassenKann();
      ... nächster Teil der Arbeit von Job1
      TueWasManNichtLassenKann();
      ... nächster Teil der Arbeit von Job1
    }
    Gibt es mehrere Dinge, die man in TueWasManNichtLassenKann() erledigen muss, dies aber nicht auf einmal machen will, wäre dafür die Lösung in einer kleinen State-Machine. Alternative Implementierung als Array von Funktionszeigern: Der Array-Index wird bei jedem Aufruf erhöht und die entsprechende Funktion aufgerufen. Komplexeres Verhalten lässt sich durch Variation der Index-Bestimmung ermöglichen.

    Viele Grüße
    RedBaron

  9. #19
    HaWe
    Gast
    Herausspringen zur aufrufenden Funktion ist ja einfach mit return, entweder mit oder ohne weitere Parameter.

    Zum Zurückspringen:
    wie wäre es, wenn man der Funktion z.B. zusätzlich zur eigentlichen 1. Variable (usw.) einen weiteren Parameter übergibt, der den Sprungpunkt definiert?
    Code:
    int function_foo(int var1, int jaddr){
       // (Deklarationsteil)
       
       if(jaddr==0) goto LABEL0;
       else
       if(jaddr==1) goto LABEL1;
       else
       if(jaddr==2) goto LABEL2;
       // usw.
    
       //...
    LABEL0:
       //...(Anweisungen)
    
    LABEL1:
       //...(Anweisungen)
    
    LABEL2:
       //...(Anweisungen)
    
    }
    Geändert von HaWe (21.09.2015 um 16:12 Uhr)

  10. #20
    Neuer Benutzer Öfters hier
    Registriert seit
    24.05.2012
    Beiträge
    14
    Hat sich seit meinem letzten Besuch ja einiges getan ;D. Ja im Prinzip hab ich nach einem Multitasking-Light gesucht. Und zumindest für meinen UseCase tuts das Kooperative Multitasking via State-Machine.
    Sollte eine Task nicht kooperieren, also hängen bleiben, ist der Kontroller in einem Fehlerzustand, aus dem er sich nicht mehr retten kann. Ein Fall der nicht auftreten darf/soll.

    Abgesehen von dem Aufwand der für das Multitasking getrieben werden muss, kommt dann noch die globale Fehlerbehandlung dazu: wie wird reagiert, wenn ein Task nicht beendet werden kann.

    Das sind für ein kleines Projekt zu viele unbekannte Zustände und führt zu unvorhersehbaren Problemen.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ähnliche Themen

  1. Nach ISR in beliebige Funktion springen? Wie? Inline-Asm?
    Von Manu_91 im Forum C - Programmierung (GCC u.a.)
    Antworten: 15
    Letzter Beitrag: 17.09.2015, 08:56
  2. ein Int-Array einer Funktion
    Von oderlachs im Forum Arduino -Plattform
    Antworten: 13
    Letzter Beitrag: 17.02.2014, 22:50
  3. Stack beim verlassen einer Schleife...
    Von Klingon77 im Forum Software, Algorithmen und KI
    Antworten: 10
    Letzter Beitrag: 26.04.2009, 10:17
  4. Funktion gibt Funktion zurück... nächstes Problem
    Von Jaecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 19.12.2008, 08:51
  5. Funktion als Rückgabewert einer Funktion?
    Von Jaecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 08.09.2008, 10:25

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress