TIA Wenn ein PEW als Eingang an einem FC nicht erreichbar ist, wird FC nicht bearbeitet

Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo ducati,

für die S7-1500 steht meines Wissen auch der Befehl PEEK für eine solche Zuweisung zur Verfügung.
Ich glaube dann darf der Baustein sogar optimiert sein.
 
Vielleicht kann ja jemand mal testen, ob der Fehler auch in SCL/FUP auftritt, oder nur bei AWL.

Und ob das nur passiert wenn das PEW mit Zugriffsfehler als Parameter übergeben wird, oder auch als letzte Anweisung vor dem Call.
 
Die Erklärung, warum in dem Fall die Funktion nicht aufgerufen wird, wäre auf jeden Fall interessant.
Ich habe bei der 1200 schon mal versucht etwas über den Befehlssatz der SPS herauszufinden. Es scheint zumindest, dass bestimmte Anweisungen erlauben das EN/ENO-Flag zu setzen, oder auch in Abhängigkeit vom EN-Flag ausgeführt zu werden (d.h. ohne Sprünge). Das ist aber nur aktiv, wenn der Haken bei "ENO automatisch setzen" gesetzt wurde. Diese Option ist bei AWL-Bausteinen jedoch nicht vorhanden.
Wenn der Call-Befehl jetzt auch an das EN-Flag gekoppelt ist, und bei einem fehlerhaften Zugriff würde dieses zurückgesetzt, dann könnte das eine Ursache sein. Oder da werden irgendwelche Registerinhalte nach dem Aufruf des Fehler-OBs nicht gesichert/zurückgesichert.
Ich habe mir den erzeugten Code bei der 1500, im Speziellen bei AWL, aber noch nicht angeschaut.

Beim nächsten Servicepack steht dann wieder nur "das Verhalten beim Zugriff auf Peripherieadressen wurde verbessert".
 
Ich kann mir lebhaft vorstellen, wo der Bug herkommt. Ich glaube nicht, daß der Bug etwas mit dem EN/ENO-Mechanismus zu tun hat. Ich glaube eher, das hat was damit zu tun, daß jede "Hochsprachen"-Quelltext-Anweisung in (jeweils mehrere Maschinenbefehle lange) Sequenzen compiliert wird und es vielleicht nicht sinnvoll ist, bei einem Fehler direkt den nächsten Maschinensprach-Befehl auszuführen, sondern zum Anfang der nächsten Sequenz bzw. "Hochsprachen"-Quelltext-Anweisung zu springen. Allerding besteht ein Baustein-Aufruf aus mehr als einer Sequenz/Teilaufgabe, was die Compilerbauer/-optimierer vermutlich fehlerhaft umgesetzt haben...

Testet mal folgenden Code:
Code:
      CALL  "FC01"
       IN_WORD_1:=%EW204:P
       IN_WORD_2:=%EW206:P

      NOP 0
Erzeugt der Code 2 Diagnosepuffereinträge für 2 Peripheriezugriffsfehler?
Diagnosepuffer schrieb:
... Temporärer CPU-Fehler: Fehler beim Lesezugriff auf Peripherie (E-Adresse 206) in OB 1
... Temporärer CPU-Fehler: Fehler beim Lesezugriff auf Peripherie (E-Adresse 204) in OB 1
Ich vermute, schon der erste Fehler führt zum kompletten Abbruch der CALL-Bearbeitung und es wird keinen zweiten Peripheriezugriffsfehler (zur E-Adresse 206) geben. (was aber "natürlich" falsch wäre)

Ich vermute, der obige Code wird in etwa solchen fiktiven Maschinencode compiliert:
Code:
1    L    PEW204    //PEW204 lesen
2    T    LW50      // und den Wert auf Parameterstack legen
3    L    PEW206    //PEW206 lesen
4    T    LW52      // und den Wert auf Parameterstack legen
5    L    P#L50.0   //Anfangsadresse des benutzten Parameterstacks
6    T    PSBP      // in Parameterstack-Basepointer für FC legen
7    CALL FC1       //FC1 aufrufen
8    NOP 0
Wenn jetzt bei der Anweisung in Zeile 1 ein Peripheriezugriffsfehler auftritt, dann wird das Programm unterbrochen, ein Diagnosepuffereintrag erzeugt, dann der OB122 aufgerufen und danach zur Anweisung nach der fehlerhaften Anweisung gesprungen - bei S7-300/400 wäre das die Zeile 2. Bei der S7-1500 haben die Compilerbauer vermutlich so implementiert, daß zur nächsten "Hochsprachen"-Anweisung gesprungen wird - das wäre zur Zeile 8.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, das ist auch denkbar. Das müsste man feststellen können, ob es einen Unterschied macht wenn es einer der ersten oder der letzte Parameter ist.

Bei meiner 1200 an der ich da mal nachgeforscht habe, die allerdings kein AWL kann, gibt es beim Aufruf eines Bausteins einen Call-Frame.

Beispiel SCL-Quelle:
Code:
MW0 := 17476;
TestFcAddInt(
  IN1:=12,
  IN2:=34,
  OUT=>"MW2"
);
MW0 := 17476;

Und generiert wird so ganz grob (alles meine Interpretation):
Code:
SET                #BoolStack@01                                                // Setze Bit <1:OUT>
MOVE               [WORD] M0, 0x4444                                            // Lade und transferiere <1:OUT, 2:IN>
CALL               Params#0x0002, 1                                             // Call Befehl einleiten <1:PARAM, 2:NR>
MOVE               [WORD] #IntStack@03, 0x0C                                    // Lade und transferiere <1:OUT, 2:IN>
MOVE               [WORD] #IntStack@07, 0x22                                    // Lade und transferiere <1:OUT, 2:IN>
CALL_EXECUTE                                                                    // Call Befehl ausführen
MOVE               [WORD] M2, #IntStack@11                                      // Lade und transferiere <1:OUT, 2:IN>
CALL_FRAME_CLEAR                                                                // Call Befehl abschließen
MOVE               [WORD] M0, 0x4444                                            // Lade und transferiere <1:OUT, 2:IN>
RET                #BoolStack@01                                                // Bausteinende <1:IN>
Wie das ganz genau mit der Parameterübergabe funktioniert habe ich auch nicht nachvollziehen können, ob PEWs anders behandelt werden habe ich noch nicht getestet. Es gibt aber definitiv diese beiden Anweisungen für den Call und Call-Frame-Clear.
Dann würde bei einem Fehler evtl. aus diesem Call-Frame herausgesprungen.
 
S7-1500 habe ich keine, in der S7-300 funktioniert folgendes:
Code:
      CALL  "MyFC"
       IN_PEW:=PEW204


//Im FC "MyFC":
//  IN: IN_PEW : POINTER

      L     P##IN_PEW           //Adresse des FC-IN-Parameters IN_PEW (Typ POINTER)
      LAR1

      L     D [AR1,P#2.0]       // Speicherbereich + Adresse aus dem außen angeschalteten POINTER
      LAR1                      //P#P204.0 = 16#80 + 16#000660

      L     PEW [AR1,P#0.0]     //lesen des Peripherieeingangs (entspricht: L PEW204)
//    diese Anweisung löst ggf. den OB122 wegen Peripheriezugriffsfehler aus

Harald

Hallo Harald,

für ein PEW funktioniert der Code soweit auch unter 1500.

aber:
Deinige meiner Bausteine werden am Eingang (INTEGER) wahlweise mit PEW, EW, MW, db1.dbw0 oder sogar mit einer Temp.Variablen beschaltet...
Hast Du ne Idee für "bereichsübergreifende Zeiger" also wo auch der Operandenbereich bzw. auch der DB mit im Pointer übergeben wird?
Zumindest falls es nicht 30 Zeilen Code werden.

Auf ne kurzfristige Lösung von Siemens will ich nicht vertrauen.

Gruß.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Deinige meiner Bausteine werden am Eingang (INTEGER) wahlweise mit PEW, EW, MW, db1.dbw0 oder sogar mit einer Temp.Variablen beschaltet....

Hab jetzt die Lösung für PEW, EW, MW, und Temp. DB ist erstmal egal...

Code:
      CALL  "MyFC"
       IN_PEW:=PEW204


//Im FC "MyFC":
//  IN: IN_PEW : POINTER

      L     P##IN_PEW           //Adresse des FC-IN-Parameters IN_PEW (Typ POINTER)
      LAR1

      L     D [AR1,P#2.0]       // Speicherbereich + Adresse aus dem außen angeschalteten POINTER
      LAR1                      //P#P204.0 = 16#80 + 16#000660

      L     [B]W[/B] [AR1,P#0.0]     //lesen des Wortes
//    diese Anweisung löst ggf. den OB122 wegen Peripheriezugriffsfehler aus

Danke Dir.

Jetzt warte ich mal auf Siemens.
 
Antwort vom 2.Level Support :

das von Ihnen beschriebene Verhalten konnten wir bei uns nachvollziehen.
Für weitere Untersuchungen Ihrer Anfrage haben wir unsere Entwicklung hinzugeschaltet.
Über den Fortgang der Untersuchung werden wir Sie auf dem Laufenden halten.

Als Workaround empfehle ich Ihnen direkte Peripheriezugriffe zu meiden. In der S7 1500 liegen sämtliche E/A Module innerhalb des Prozessabbilds bzw. einem TPA. Der Zugriff auf das Prozessabbild ist immer ein definierter Zugriff, es kann dadurch im Anwenderprogramm kein Programmierfehler auftreten.

wobei bei mir im Anwenderprogramm kein Programmierfehler vorliegt, sondern das entsprechende PEW zur Zeit nur nicht erreichbar ist, weil ich der ET200S die 24V geklaut habe...
 
Zuletzt bearbeitet:
so, jetzt noch der Workaround von PN/DP und modifiziert von mir und meinem Kollegen:

funktioniert jetzt für Verschaltungen von PEW, EW, MW, Temp. und DB-Variablen für nicht optimierte FC/FB:

Code:
//Im FC "MyFC":
//  IN: IN_POINTER : POINTER
// Temp: Adr_0 : WORD
// Temp: Adr_2 : DWORD

      L     P##IN_POINTER
      LAR1

      L W [ AR1 , P#0.0 ]
      T     #Adr_0
      L D [ AR1 , P#2.0 ]
      T     #Adr_2

      L     #Adr_0
      L     0
      ==I
      SPB   XXX1
      AUF DB [ #Adr_0]
XXX1: NOP 0

      L D [ AR1 , P#2.0 ]
      LAR1
      L W [ AR1 , P#0.0 ] // Lesen des Wortes, diese Anweisung löst ggf. den OB122 wegen Peripheriezugriffsfehler aus
      T MW100      // hier liegt der Wert vom eingelesenen Signal
 
Zuviel Werbung?
-> Hier kostenlos registrieren
so, jetzt noch der Workaround von PN/DP und modifiziert von mir und meinem Kollegen:

Ist DAS ein IRRSINN. Und alles das nur für ein völlig absurdes Verhalten von TIA. Seid ihr Selbständig oder Angestellte in einer
Firma? Solchen MIST für größere Projekte nun "vorübergehend" nachrüsten zu müssen, kann sich ein Freelancer eigentlich
gar nicht leisten. Absurdes Theater.
 
Ist DAS ein IRRSINN. Und alles das nur für ein völlig absurdes Verhalten von TIA. Seid ihr Selbständig oder Angestellte in einer
Firma? Solchen MIST für größere Projekte nun "vorübergehend" nachrüsten zu müssen, kann sich ein Freelancer eigentlich
gar nicht leisten. Absurdes Theater.

Mein Problem ist nur, dass dieser Irrsinn mir und meinem Kollegen 3 Tage meiner eh schon knappen Projektzeit gekostet hat. Welche ich jetzt irgendwie wieder reinholen muss. Bezahlen muss das mein Chef ;)

Als Freiberufler kannst Du eigentlich keine TIA-Projekte auf pauschaler Abrechnung umsetzen ;)

Hoffe diesen Thread hier lesen auch die 2-3 TIA Befürworter hier im Forum

Gruß.
 
Zuletzt bearbeitet:
Ich habe es jetzt auch gelesen.

Ich kann nachvollziehen das der Fehler ärgerlich ist auch wenn er mich nicht betrifft.

Mir ist vor einer Weile mal der GET_ERROR Baustein aufgefallen.
Dort gibt es den Hinweis.

Hinweis
Die Anweisung "Fehler lokal abfragen" aktiviert die lokale Fehlerbehandlung innerhalb eines Bausteins. Wenn "Fehler lokal abfragen" im Programmcode eines Bausteins eingefügt ist, werden voreingestellte Systemreaktionen beim Auftreten von Fehlern ignoriert.

Könnte es sich hier um so eine Systemreaktion handeln bei dir ?

Get_Error.jpg

Weiterhin heißt es bei der lokalen Fehlerbehandlung

Wenn Fehler während der Bearbeitung eines Bausteins mit lokaler Fehlerbehandlung auftreten, wird eine voreingestellte Reaktion abhängig von den folgenden Fehlerarten ausgelöst:

  • Schreibfehler: Die Fehler werden ignoriert und die Bearbeitung des Programms einfach fortgesetzt.
  • Lesefehler: Die Bearbeitung des Programms wird mit dem Ersatzwert "0" fortgesetzt.

Das klingt fast so als ob die Globale Fehlerbehandlung die Bearbeitung abbricht, bzw. nach dem von Dir beschriebenen Verhalten.

LokaleFehlerbehandlung.jpg
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, es werden 2 Zugriffsfehler im Diagnosepuffer angezeigt, Baustein wird trotzdem NICHT bearbeitet.
Es scheint so, als ob bei dem Bug wohl tatsächlich fälschlicherweise der EN-Mechanismus zuschlägt, so wie von Thomas in #44 vermutet.

Hilft vielleicht ein explizites "SET" direkt vor dem "CALL FC..."? Oder ein Aufruf des FC in FUP/KOP mit explizit verschaltetem EN-Eingang mit einem AlwaysTrue-Bool?


Zum Workaround mit der Übergabe als POINTER: hier eine Variante, die funktioniert mit Verschaltungen mit PE, E, A, M, L und DB/DI für nicht optimierte FC
Code:
//FC "MyFC":
// IN  : IN_POINTER : POINTER
// TEMP: DB_Nr : WORD

      L     P##IN_POINTER               //Adresse des FC-IN-Parameters IN_POINTER (Typ POINTER)
      LAR1  

      L     W [AR1,P#0.0]               //DB-Nummer aus dem außen angeschlossenen POINTER
      T     #DB_Nr

      L     D [AR1,P#2.0]               //Speicherbereich + Adresse aus dem außen angeschlossenen POINTER
      LAR1

//Lesen des Wortes, auf das der verschaltete POINTER zeigt, aus PE/E/A/M/L/DB/DI
      AUF   DB [#DB_Nr]                 // (*)
      L     W [AR1,P#0.0]               //Lesen des Wortes, auf das der POINTER zeigt
      T     #MyValue                    //der Wert vom eingelesenen Signal

(*)
Bei S7-1500: Die AUF-Anweisung eventuell nur ausführen, wenn der Speicherbereich des Pointers "DB" (B#16#84) oder "DI" (B#16#85) ist.

Bei S7-300: die AUF-Anweisung muß nicht übersprungen werden, sie kann immer ausgeführt werden, weil bei POINTERN mit korrektem Format bei allen Speicherbereichen außer DB und DI die DB-Nummer 0 ist und "AUF DB 0" keinen Fehler wirft. Sollte bei einem POINTER inkorrekterweise eine DB-Nummer <> 0 enthalten sein, so stört das "AUF DB x" hier nicht - es sei denn, der DB existiert nicht, dann wird ein Programmierfehler (OB121) gemeldet.

Hinweise:
  • ein POINTER enthält keine Information über Größe oder Datentyp des adressierten Bereiches, sondern nur die Anfangsadresse. Der FC kann daher nicht prüfen, ob außen z.B. EW200, EB200, ED200 oder E200.0 verschaltet ist --> er liest in allen Fällen EW200
  • Vorsicht beim Verschalten von BOOL: der FC prüft/korrigiert nicht, ob die Bitadresse .0 ist --> ein Verschalten von z.B. E200.3 löst einen Ausrichtungsfehler-Programmierfehler (OB121) aus.
  • Wenn ein POINTER auf Peripherieadressen zeigt, dann adressiert ein Lesezugriff immer PE..., ein Schreibzugriff adressiert immer PA...


PS:
Beitrag #36

wie kriege ich einen Link dazu hier rein?
Die Linkadresse kopieren, die beim Beitrag oben rechts auf dem #36 liegt.

Harald
 
Was passiert eigentlich, wenn im folgenden Code das DB10.DBW100 nicht existiert? Wird der FC dann ebenfalls nicht aufgerufen?
Code:
      CALL  "FC01"
       IN_WORD:=DB10.DBW100

Harald
 
Was passiert eigentlich, wenn im folgenden Code das DB10.DBW100 nicht existiert? Wird der FC dann ebenfalls nicht aufgerufen?
Code:
      CALL  "FC01"
       IN_WORD:=DB10.DBW100

Harald

Jo, dann wird der FC auch nicht bearbeitet !!! (Der Compiler bringt aber ne Warnmeldung und falls OB121 nicht vorhanden ist, dann geht die CPU in STOP)

Ein SET vor dem CALL bringt nix.

KOP/FUP hab ich noch nicht probiert

Gruß.
 
Zuletzt bearbeitet:
Zurück
Oben