Programm wird von mehreren Tasks ausgerufen

Anonymous
2008-07-01
2008-10-15
  • Anonymous - 2008-07-01

    Originally created by: mg

    ... nur mal eine blöde Frage:

    Kann ich ein Programm (=PRG - nicht FB) von mehreren Tasks aus aufrufen. Was passiert wenn ein Task gestartet wird, der eine höhere Priorität hat oder wird immer zuerst das Programm abgeschlossen bevor es von einem anderen Task nochmals gestartet werden kann.

    ODER wird das Programm ein 2. Mal geöffnet und die Variablen sind unterschiedlich (wie beim Funktionsblock)

    Ich habe viele unerklärliche Abstürze beim Controller und bin auf der Fehlersuche. Lt Codesys-Beschreibung sollte es zu keinen Fehlern kommen, aber vielleicht habe ich das falsch aufgefaßt.

    Vielen Dank für Eure Informationen.

     
  • Matze001 - 2008-07-01

    Guten Abend,

    ich kenne es nur so das FB mehrmals geöffnet werden können.

    Bei einem PRG kann es passieren das Variablen gleichzeitig geschrieben werden, was dann zu Fehlern führt.

    MfG

    Marcel

     
  • Anonymous - 2008-07-01

    Originally created by: Andy :-)

    Hallo mg,

    jede Task hat eine Priorität (0..xx).

    Die Task mit der höhsten Priorität (0=höchste Prio) unterbricht die andere.

    Aber:

    Habe ich das richtig verstanden, Du rufst ein Programm in verschieden Task (gleichzeitig) auf ???

    mfg

    Andy

     
  • Anonymous - 2008-07-01

    Originally created by: Andy :-)

    sorry... nicht richtig gelesen

    also passieren wird letzteres...

    Deshalb muß man sehr vorsichtig mit den verwendeten (globalen) Variablen sein.

    Einen Programmaufruf in verschiedenen Task halte ich aber für "murks". Was möchtest Du damit erreichen/bewerkstelligen ?

    mfg

    Andy

     
  • Anonymous - 2008-07-02

    Originally created by: mg

    ich hätte da 2 Ideen (oder schon ausgeführt, aber da ich Probleme mit der PLC habe ... und nun denke ich mir das könnte einer der Fehler sein - sieht aber derzeit nicht danach aus - aber man kann ja mal fragen):

    Im Normalfall werden die 2 Programme zyklisch abgearbeitet. (zB jede Minute)

    1) ich verwende die Funktion CALLBACKSTART, die 2 Programme werden von dort aus aufgerufen: dh in meinem Fall werden die 2 Programme beim Start der PLC in jedem Fall zuerst abgearbeitet.

    2) Es kann sein, daß bei bestimmten Eingaben (über die Visu) diese beiden Programme SOFORT (Start über "Ereignis" der Tasksteuerung) abgearbeitet werden sollen.

    ... da es sich um eine Datenaufzeichung handelt und auf eine Datei geschreiben wird, ist es für mich eigentlich egal, ob mit Funktionsblock oder mit Programm. Die Datei gibts nur 1x. Globale Variablen werden so gut es geht nicht verwendet ... zumindest kann es lt. meinen Überlegungen zu keinen Konflikten kommen. Am liebsten wäre es mir sowieso, wenn das Prg zuerst abgearbeitet wird bevor es erneut gestartet wird.

    ... natürlich ist es kein Problem, die 2 Programmteile als FunctionBlock umzuschreiben. Soll nur mal eine Frage sein, ob das geht und zu was für Reaktionen das führen kann. (... ist ja nicht SOOO außergewöhnlich ... und beim Programmieren schnell mal passiert)

     
  • Uwe - 2008-07-02

    Hallo mg,

    also ich denke FB's lösen dein Problem auch nicht.

    Für dein Problem gibt es Semaphore.

    Du musst als erstes in deinem PRG einen Sema belegen

    und am Ende wieder freigeben.

    Ich würde dafür nicht den Soft-Sema aus der Standard-lib

    nehmen, da dieser unterbrechbar ist.

    (Wozu braucht man eigentlich einen unterbrechbaren Semaphor ?)

    Ich würde die Funktionen aus der Bibliothek SysLibSem.lib benutzen.

    Diese Funktionen sind auch in der Hilfe beschrieben

    Uwe

     
  • Anonymous - 2008-07-02

    Originally created by: mg

    Hallo Uwe

    ... das klingt gut ...!

    ABER hat da irgendwer vielleicht ein kleines Beispiel dafür. Ich habe mir das kurz angeschaut. Ich verstehe nur Bahnhof Muss das vor dem Variablenzugriff stehen? Und wie sage ich der lib welche Variablen, ich für kritisch halte? Oder hat das mit der Taskabarbeitung zu tun. Aber dann weiß ich nicht wie ich das ins Codesys einbinden soll.

    Der Controller hat die Lib offensichtlich. (... ist noch nicht ganz sicher, weil ich nicht weiß was ich damit tun soll)

    Danke

     
  • Uwe - 2008-07-02

    Hallo mg,

    als erstes legst du eine globale Variable an

    VAR_GLOBAL
       g_mySema      :   DWORD := 16#FFFF_FFFF;
    END_VAR
    

    und dein PRG musst du dann so modifizieren

    (*--- Falls der Sema noch nicht erzeugt wurde --------------------------*)
    IF g_mySema = 16#FFFF_FFFF THEN (* neuen Sema erzeugen *)
       g_mySema := SysSemCreate(TRUE);
    END_IF
    (*--------------------------------------------------------------------------------------*)
    IF NOT SysSemEnter(g_mySema) THEN
       RETURN;    (* PRG beenden wenn der Sema schon von irgendjemanden belegt ist *)
    END_IF
    (* so wenn ich hier bin dann war der Sema frei und ich habe ihn belegt *)
    (* hier steht mein code der nicht unterbrochen werden soll *)
    (* . *)
    (* . *)
    (* . *)
    (* . *)
    (*--- Ich habe den Sema belegt-> also muß ich ihn auch freigeben *)
    SysSemLeave(g_mySema);
    

    Habe ich jetzt so kurzfristig nicht getestet.

    Kann also noch nen Tippfehler drin sein sollte aber prinzipiell so funktionieren.

    Gruß

    Uwe

     
  • Uwe - 2008-07-02

    Ich schieb noch ein paar Info's für Interessierte nach weil mir das Thema für alle Task-Fetischisten wichtig erscheint.

    Also das Grundprinzip ist folgendes :

    Die Task die mit Daten hantiert die nicht gleichzeitig von einer anderen

    Task benutzt werden sollen

    die schaut auf ein für alle Mitspieler sichtbares Bit ob die Daten gerade frei sind oder von jemanden benutzt werden.

    Wenn dieses Bit gesetzt ist dann löscht diese Task das Bit, signalisiert hiermit den Anderen die Belegung

    und kann nun die Daten benutzen.

    Nach der Benutzung muss die Task das Bit natürlich wieder setzen (freigeben) damit die Daten für die Anderen

    und natürlich auch für sich selbst beim nächsten Aufruf wieder frei sind.

    Die anderen Task müssen es natürlich genauso machen und sich an diese Spielregeln halten sonst geht's schief .

    Prinzipiell sieht es so aus

    -----PROBLEMZONE--------------

    IF NOT Bit THEN

    RETURN;

    END_IF

    Bit := FALSE;


    ( Bearbeitung der Daten jeweils nur von einer Task )

    Bit := TRUE; // Die Daten / Resourcen wieder freigeben

    Im obigen Beispiel gibt es eine Problemzone in der eine zweite Task

    die Erste unterbrechen könnte und auch das Bit abfragt bevor die Erste

    das Bit belegt hat.

    Es könnten beide Task das Bit abgefragt haben und beide haben es als TRUE

    also Daten frei erkannt.

    Um diese Problematik zu lösen gibt es Semaphore.

    Semaphore können in einer atomaren Einheit (also nicht unterbrechbar)

    dieses Bit abfragen und ggf. auch belegen.

    Gruß

    Uwe

     
  • Anonymous - 2008-07-04

    Originally created by: mg

    ... Danke nochmals. Ich hatte das nicht gewußt und auch bisher nicht beachtet (was aber SEHR wichtig ist)
    

    ... hat zwar die Probleme mit meinem Wahnsinns-Controller nicht gelöst, aber ich werde in Zukunft diese Problematik im Kopf behalten.

     
  • Anonymous - 2008-07-04

    Originally created by: Bernhard Werner

    Noch eine Anmerkung zu:

    Uwe hat geschrieben:

    zu gar nichts und aus neueren Versionen der Standardlib ist der Baustein auch rausgeflogen. Stand so mal explizit in der Norm, keine Ahnung was die Idee dahinter war, dort ist er aber denke ich auch entfernt worden.

    Für die 3x haben wir als Sprachmittel mal dne Operator TEST_AND_SET reserviert. Mit dem liesse sich ein Semaphor auch in IEC schreiben.

    Bernhard Werner

     
  • Anonymous - 2008-07-06

    Originally created by: mg

    Hallo Bernhard

    ... zuerst mal, es geht um die Version 2.9.X

    ... warum braucht man das nicht. ... und nun nochmals die Frage auch an Dich. Was passiert wenn ich ein Programm ("PRG") von einem Task mit höherer Priorität aufrufe, aber das Programm momentan gerade von einem anderen Task abgearbeitet wird? UND insbesondere dann, wenn zB eine Datei geschreiben wird - Greift das Teil dann gleichzeitig auf die Datei zu? UND da die meisten PLC eine maximal geöffnete Anzahl von Dateien vorgeben - werden die dann u.U. unwillkürlich überschritten usw.

    Soll nur eine grundlegende Frage sein. Meine PLC betrifft das eh nicht. Die stürzt mit oder ohne Semaphore ab. Aber mich würde das Thema schon sehr interessieren.

    Danke

     
  • Belacqua - 2008-07-07

    Moin!

    Das braucht man deshalb nicht weil man mit Semaphoren sicherstellen will, dass kein anderer Task als derjenige der den Semaphor belegt hat auf die Daten zugreifen können soll. Ein unterbrechbarere Semaphor ist daher genau so gut wie gar keinen zu verwenden.

    Was genau passiert wenn ein höherpriorer Task den aktuellen unterbricht und auf die gleichen Daten zugreift ist im allgemeinen unberechenbar und daher streng zu vermeiden da die Fehlersuche schon so manchen an den Rand des Wahnsinns gebracht hat. Daher hat irgendwann einmal jemand Semaphore erfunden - die ein wesentlicher Grundbaustein von Multitasking-Applikationen sind.

     
  • Anonymous - 2008-07-07

    Originally created by: mg

    Entschuldigung!

    Habe das Wörtchen "unterbrechbar" einfach überlesen. Nun ist mir diese Diskussion klar.

     
  • Anonymous - 2008-07-10

    Originally created by: Bernhard Werner

    mg hat geschrieben:
    Was passiert wenn ich ein Programm ("PRG") von einem Task mit höherer Priorität aufrufe, aber das Programm momentan gerade von einem anderen Task abgearbeitet wird? UND insbesondere dann, wenn zB eine Datei geschreiben wird - Greift das Teil dann gleichzeitig auf die Datei zu? UND da die meisten PLC eine maximal geöffnete Anzahl von Dateien vorgeben - werden die dann u.U. unwillkürlich überschritten usw.

    Es kommt natürlich darauf an was das Dateisystem zu einem zweimaligen öffnen sagt, in der Regel funktioniert das einfach gar nicht, bis die Datei wieder geschlossen wird.

    Dennoch: Es passieren die schlimmsten Dinge. Multithreading (und um das handelt es sich bei IEC-Tasks) ist des Teufels. Mit Semaphore hat man auch noch längst nicht alle Probleme aus der Welt geschafft. Dann muss man erstmal nachweisen dass es nicht zu Verklemmungen kommen kann.

    Man sollte am besten überhaupt keine Programme in zwei Tasks verwenden. Nur Funktionen kann man mit Einschränkung problemlos in zwei Tasks aufrufen, dazu dürfen sie aber nicht auf globale Variablen zugreifen oder statische Zustände haben.

    Bernhard

     
  • Anonymous - 2008-10-15

    Originally created by: mg

    zu den unerklärlichen Abstürzen muß ich nun erwähnen es war NICHT von der Software abhängig:

    Der Controller hatte Probleme mit den ereignishabhängigen Tasks und stürzte deshalb immer wieder ab. Ich habe die Software umgeschreiben und es funktionierte VIEL besser.

     

Log in to post a comment.