Step 7 Frage zu temporären Variablen bei asynchronen Unterbrechungen( Step7 V5.5 / CPU 315 )

Welche SPS hast Du genau? CPU315-2 PN/DP 6ES7315-2EH14-0AB0 ? Firmware V3.2.16 ?
Welche Step7-Version genau?

Der FB35 wird nur im OB1 aufgerufen, oder auch in dem OB3x?
Wie lautet Dein Testcode genau? Hast Du vielleicht Variablen-Überschneidungen (nicht TEMP)?

Z.B. so kann es passieren, daß in MW100 50 drin steht, obwohl 51 reingeschrieben wurde:
Code:
//FB35

FOR hv := 0 TO 50 BY 1 DO
    "Daten".ZumPC[hv] := 0;
END_FOR;

MW100 := hv; //oder mal fest: MW100 := 51;
Code:
//OB3x
IF ...
    M101.0 := 0;
END_IF;

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
elche SPS hast Du genau? CPU315-2 PN/DP 6ES7315-2EH14-0AB0 ? Firmware V3.2.16 ?
Genau, 6ES7315-2EH14-0AB0, FW3.2.16

Welche Step7-Version genau?
Step7 V5.5 + SP4 + HF11

Der FB35 wird nur im OB1 aufgerufen, oder auch in dem OB3x?
Nur 1x im OB1

Hast Du vielleicht Variablen-Überschneidungen
Wurde bereits ausgeschlossen.


Code:
//FB35

FOR hv := 0 TO 50 BY 1 DO
    "Daten".ZumPC[hv] := 0;
END_FOR;

MW100 := hv; //oder mal fest: MW100 := 51;
Ich verstehe deine Beispiele, es ist auch klar, das hv nach dem END_FOR; auf 51 steht.



Wenn ich die hv wieder auf VAR_TEMP verschiebe und folgendes reinprogrammiere:

Code:
VAR
    testInt : INT;
END_VAR

VAR_TEMP
    hv : INT;
END_VAR



FOR hv := 0 TO 50 BY 1 DO
    
    IF hv > testInt THEN
        testInt := hv;
    END_IF;
    
    "Daten".ZumPC[hv] := 0;

END_FOR;

Dann steht testINT für einige Sekunden auf 50 und dann auf einmal auf 51
TestInt ist frisch angelegt, DB generiert, alles konsistent geladen. Verschiebe
ich hv von VAR_TEMP zu VAR dann bleibt testInt auf 50 dauerhaft.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
FOR hv := 0 TO 50 BY 1 DO
    
    IF hv > testInt THEN
        testInt := hv;
    END_IF;
    
    "Daten".ZumPC[hv] := 0;

END_FOR;

Dann steht testINT für einige Sekunden auf 50 und dann auf einmal auf 51
Es kann auch sein daß nur falsch/unglücklich beobachtet wird. Wird testInt in jedem Zyklus vor der Schleife auf 0 zurückgesetzt? Weil dann in jedem Zyklus jeder Wert von 1...51 in testInt geschrieben wird. Ist bei Deiner CPU "priorisierte BuB" aktiviert? Oder versucht Dein Beobachtungstool den Wert in jedem Schleifendurchlauf anzuzeigen und nicht nur am Zyklusende? Füge mal dies hinzu und beobachte testInt2
Code:
...
END_FOR;

[COLOR="#0000FF"]testInt2 := testInt;[/COLOR]

Harald
 
Wird testInt in jedem Zyklus vor der Schleife auf 0 zurückgesetzt?
Nein, er wird aber auch nur an dieser Stelle beschrieben, es sollte also der höchste aufgetretene Wert drin stehen.

Ist bei Deiner CPU "priorisierte BuB" aktiviert?
Nein, ist deaktiviert.


Oder versucht Dein Beobachtungstool den Wert in jedem Schleifendurchlauf anzuzeigen
Es sollte doch im Prinzip egal sein, es wird der höchste aufgetretene Wert in TestInt geschrieben,
TestInt wird nirgendwo abgelöscht oder sonstig beeinflusst. Ich beobachte über eine VAT

...
END_FOR;

testInt2 := testInt;

Ich habe es probiert.

TestInt ( innerhalb der Schleife ) steht auf 51
TestInt2 steht auch auf 51
 
Zuviel Werbung?
-> Hier kostenlos registrieren
kannst du mal den Inhalt vom OB32/35 posten?

Code:
 ORGANIZATION_BLOCK OB35
 
//********************
// Temporäre Variablen
//********************
VAR_TEMP
    OB35_EV_CLASS :   BYTE;          // Ereignisklasse und Kennungen: B#16#11: OB 1 ist aktiv
    OB35_STRT_INF :     BYTE;         // B#16#01: Abschluss des Neustarts (Warmstarts); B#16#02: Abschluss des Wiederanlaufs; B#16#03: Abschluss des freien Zyklus; 
                                                      // B#16#04: Abschluss des Kaltstarts; B#16#05: Erster OB 1-Zyklus der neuen Master-CPU nach Master-Reserve-Umschaltung und STOP des bisherigen Masters
    OB35_PRIORITY :   BYTE;              // Prioritätsklasse: 1 
    OB35_OB_NUMBR :   BYTE;           // OB-Nr. (01)
    OB35_RESERVED_1 : BYTE;          // Reserviert
    OB35_RESERVED_2 : BYTE;          // Reserviert
    OB35_PHS_OFFSET : INT;            // Laufzeit des vorherigen Zyklus (ms)
    OB35_RESERVED_3 :  INT;           // Minimale Zykluszeit (ms) seit dem letzten Anlauf
    OB35_EXC_FREQ :  INT;              // Maximale Zykluszeit (ms) seit dem letzten Anlauf
    OB35_DATE_TIME :  DATE_AND_TIME; // Datum und Uhrzeit, zu denen der OB angefordert wurde
END_VAR

//*************************
// Start Zyklisches Program
//*************************
BEGIN

"Asynchron".Zaehler100ms := "Asynchron".Zaehler100ms +1;
 

//*************************
// Ende zyklisches Program
//*************************
END_ORGANIZATION_BLOCK

OB32 ist im Prinzip das gleiche, nur mit Zaehler10ms
 
hm, hatte an ein indirektes schreiben der Lokaldaten gedacht à la:
Code:
L irgendwas
T LW   100
so könnte der OB35 auch "fremde" Lokaldaten manipulieren...
aber das ist hier ja nicht der Fall. Echt komisch.
 
Ich weiß auch nicht weiter.

Wenn ich unter VAR_TEMP im OB35 Variablen anlege, würden diese denn die Temp-Variablen des unterbrochenen FB
beeinflussen oder hat wirklich jeder seinen eigenes Stack.

In den Handbüchern liest man ja, das die Temp-Variablen bis zum Bausteinende gültig bleiben. Was ist denn das Bausteinende.
Wirklich die letzte Zeile eines Bausteins oder auch schon eine Unterbrechung dieses Bausteins ( was ja fatal wäre, also vermute ich
mal das es nicht so ist. )
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja, was heißt schon eigener Speicher. Physikalisch ist es der selbe, die CPU soll nur dafür sorgen, das jeder Baustein einen eigenen Bereich zum arbeiten bekommt. Wenn nun ein Baustein diesen Bereich verlässt (ob absichtlich oder unabsichtlich), dann kann der eine Baustein schon die Lokaldaten des anderen manipulieren.
 
Theoretisch kann ein Baustein die TEMP-Lokaldaten eines anderen Bausteins nur beeinflussen via "Vorgänger-Lokaldaten" und das geht nur mit Pointern. Ein Baustein der normal aufgerufen wird, kann den TEMP-Stack bis zur festgelegten Stackgröße "nach unten" nutzen (L0..L100..L1000...), die TEMP-Lokaldaten der aufrufenden Bausteine sollten "oberhalb" der eigenen TEMP-Lokaldaten liegen und dadurch für normale TEMP-Zugriffe unzugänglich sein (es gibt keine negativen L-Adressen). Nur auf die "Vorgänger"-Lokaldaten des aufrufenden Bausteins kann man per Pointer zugreifen.

Ich meine, ein unterbrechender OB3x sollte seinen TEMP-Stack "so weit weg" von der OB1-Stackebene haben, daß ein zugreifen auf TEMP-Speicher einer anderen OB-Ebene gar nicht geht.

@Faceman
Befrage mal den Siemens Support zu Deinem Problem, und berichte hier bitte.

Harald
 
Wird testInt in jedem Zyklus vor der Schleife auf 0 zurückgesetzt? Weil dann in jedem Zyklus jeder Wert von 1...51 in testInt geschrieben wird.
Das verstehe ich nicht, Harald. Woher käme dann in jedem Zyklus der Wert 51?
Wenn testInt NICHT vor der Schleife auf 0 zurückgesetzt würde UND testInt ein Var-Temp wäre, dann könnte die 51 vom Stack kommen und somit keine Aussage darüber machen, ob auch nv in der Schleife grösser als 50 wird.
Was passiert denn, wenn man die Schleife nicht bis 50 laufen lässt, sondern nur bis 49 oder 48 oder . . . ? Bleibt es dann bei 51?
 
Mal angenommen da gäbe es ein Überschreiben der Lokaldaten von anderer Stelle, dann ist es schon sehr unwahrscheinlich, dass dort genau diese Laufvariable mit dem Wert 51 beschrieben wird. Das würde ich darum mal zu 99,9% ausschließen.
Was dann schon eher möglich wäre, dass das die Registerinhalte wie das Statuswort nicht korrekt gesichert / zurückgesichert werden. Aber wenn das der Fall ist, dann würde das Problem so oft und auch an anderer Stelle zu Problemen führen, dass das garantiert schon aufgefallen wäre.

Ohne den gesamten betreffenden Code wird das aber sehr schwer nachzuvollziehen sein. Du könntest ja mal von dem Baustein mit Step7 einen AG-Abzug machen, oder Programm mit TIA in Plcsim laden und mit Step7 wieder herausladen, damit man sich den AWL Code einmal ansehen kann.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mal angenommen da gäbe es ein Überschreiben der Lokaldaten von anderer Stelle, dann ist es schon sehr unwahrscheinlich, dass dort genau diese Laufvariable mit dem Wert 51 beschrieben wird.
Jain. Habe ich zunächst auch gedacht und deshalb gefragt, ob der Wert 51 auch dann noch auftaucht, wenn man die Schleife nur bis 49 oder 48 laufen lässt.
Habe mit TempVariablen, die gelesen werden, bevor sie geschrieben werden, schon erlebt, dass Bausteine "reproduzierbar" scheinbar laufen bzw. "reproduzierbar" nicht laufen.
Bei Siemens und Fanuc war es StandardSoftware, in der abenteuerlicherweise TempVariablen gelesen wurden, bevor sie geschrieben wurden. Bei Fidia war's eine Macke in der CRC-Bildung bei Telegrammen, die (sorry, off Topic) nach jahrelangem, scheinbaren Wohlverhalten erst seit der Verwendung bestimmter WerkzeugDaten plötzlich das Fehlverhalten sichtbar werden liess.
Für die vermeintlichen Zufälle gibt es meist ganz simple Erklärungen, z.B. dass die Reihenfolge von BausteinAurufen geändert wird (z.B. durch Alarme).
Ich denke, dass nur Siemens hier weiterhelfen kann. Wir können hier nur sagen, wie das Verhalten "theoretisch" sein sollte und ggfs noch Beispiele weiterer FehlVerhalten hinzufügen.
 
hm, hatte an ein indirektes schreiben der Lokaldaten gedacht à la:
Code:
L irgendwas
T LW   100
so könnte der OB35 auch "fremde" Lokaldaten manipulieren...
Nein, das geht nicht. Ein Baustein (insbesondere ein OB) kann den gesamten TEMP-Stack ab LB 0 bis zur noch verfügbaren Größe nutzen und trifft dabei nicht auf fremde Lokaldaten.

Harald
 
Ab und an wird allerdings der OB122 Programmierfehler aufgerufen, klickt man auf "Gehe zu" springt er auf diese Zeile,
weil hv auf 51 steht. Der DB geht nur bis 50.
Du meinst OB121 ? Hast Du noch den genauen/kompletten Wortlaut des Diagnosepuffer-Eintrags?
(vermutlich "Bereichslängenfehler beim Schreiben")

Wird in Deinem FB35 innerhalb der FOR-hv-Schleife auf Variablen oder Speicherbereiche von VAR_TEMP indirekt oder mit BLKMOV oder anderen Bausteinen zugegriffen?

Ändert sich das Verhalten, wenn Du hv als allererste Variable in VAR_TEMP deklarierst (also an LW 0)?
Ändert sich das Verhalten, wenn Du hv als zweite oder allerletzte Variable in VAR_TEMP deklarierst, und direkt davor irgendeine Dummy-Variable (z.B. ein DWORD oder ein 20-Byte-Array)?

Ändert sich das Verhalten, wenn Du im SCL-Compiler Einstellungen änderst?
Extras > Einstellungen > Compiler
[x] Objektcode optimieren
[ ] Feldgrenzen überwachen
[x] Debug Info erstellen

Welchen AWL-Code der SCL-Compiler erzeugt kann man so sehen:
- den KOP/AWL/FUP-Editor öffnen, z.B. mit Doppelklick auf einen Baustein der als "Erstellsprache" AWL, KOP, FUP oder DB hat
- im KOP/AWL/FUP-Editor dann "Datei > Öffnen..." öffne den vom SCL-Compiler erzeugten FB35 (aus dem "Bausteine" Ordner)
Vielleicht kannst Du uns den erzeugten AWL-Code zeigen.

Harald
 
Zurück
Oben