- Beiträge
- 5.682
- Reaktionspunkte
- 1.600
-> Hier kostenlos registrieren
Ich hab hier ein paar S7-1517 3pn/dp FW 2.9 (selbes Problem bei 2.8)
Eine von 20 CPUs geht alle paar Tage bis Wochen auf Stop wegen Zugriffsfehler.
Wie könnte ich hier einen dynamisch auftretenden Zugriffsfehler provozieren?
Im Rot markierten Vereich zähle ich den Index zwar vor ende nochmal hoch. Aber ich geh dann ja wieder in die while Prüfung und dürfte da dann direkt rausfallen.
Mir gehen da die Ideen etwas aus. Das ist übrigens ein Bibliotheksbaustein, der ist noch auf 20 weiteren exakt gleich konfigurierten CPUs drauf. Aber es passiert nur bei dieser einen.
Bevor ich jetzt Zeile für Zeile mit einem Dummymerker markiere um den exakten Ausprungspunkt und Zugriffsadresse rauszufinden, dache ich. Frag mal vielleicht hat einer ne iIee.
Eine von 20 CPUs geht alle paar Tage bis Wochen auf Stop wegen Zugriffsfehler.
Der Code ist relativ kurz und übersichtlich.Temporärer CPU-Fehler: Bereichslängenfehler in FB 12
betrifft OB 1-Ausführung
Lesezugriff Flüchtiger DB-Bereich
fehlerhafte Adresse, Operand ersetzt
interne Adressierungsdetails: Caddr=16#00000103, Bereich: Flüchtiger DB-Bereich, Adr: 268436105
Code:
FUNCTION_BLOCK "FB_OBJ_Webserver"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_IN_OUT
Signal_WEB_Array : Array[*] of "Signal_OBJ_LST_WEB";
Austausch : "Signal_Austausch_1";
END_VAR
VAR
Signal_index : DInt;
END_VAR
VAR_TEMP
untereGrenze : DInt;
obereGrenze : DInt;
Laenge : Int;
index : Int;
END_VAR
BEGIN
#untereGrenze := LOWER_BOUND(ARR := #Signal_WEB_Array, DIM := 1);
#obereGrenze := UPPER_BOUND(ARR := #Signal_WEB_Array, DIM := 1);
#Laenge := DINT_TO_INT(#obereGrenze - #untereGrenze);
REGION generalabfrage
IF #Austausch.Generalabfrage THEN
FOR #index := #untereGrenze TO #obereGrenze DO
IF #Signal_WEB_Array[#index].BA <> 0 THEN
#Signal_WEB_Array[#index].New := TRUE;
END_IF;
END_FOR;
#Austausch.Generalabfrage := FALSE;
END_IF;
END_REGION
REGION Signalupdate
IF NOT (#Signal_index >= #untereGrenze AND #Signal_index <= #obereGrenze) THEN
#Signal_index := #untereGrenze;
END_IF;
IF NOT #Austausch.Signal.New THEN
WHILE #Signal_index >= #untereGrenze AND #Signal_index <= #obereGrenze DO
IF #Signal_WEB_Array[#Signal_index].New THEN
#Austausch.Signal := #Signal_WEB_Array[#Signal_index];
#Signal_WEB_Array[#Signal_index].New := FALSE;
EXIT;
END_IF;
#Signal_index += 1;
END_WHILE;
END_IF;
END_REGION
REGION lokal setzen
IF #Austausch.Signal_Set.Set THEN
FOR #index := #untereGrenze TO #obereGrenze DO
IF #Signal_WEB_Array[#index].Config.SID = #Austausch.Signal_Set.SID AND
#Signal_WEB_Array[#index].Config.LID = #Austausch.Signal_Set.LID THEN
#Austausch.Signal_Set.Set := false;
#Austausch.Signal_Set.SID := 0;
#Austausch.Signal_Set.LID := 0;
IF #Austausch.Signal_Set.BA > 0 AND #Austausch.Signal_Set.BA <= 4 THEN
#Signal_WEB_Array[#index].BA := #Austausch.Signal_Set.BA;
END_IF;
#Signal_WEB_Array[#index].Soll_LST := #Austausch.Signal_Set.Soll_LST;
#Signal_WEB_Array[#index].OverrideAktiv := #Austausch.Signal_Set.OverrideAktiv;
EXIT;
END_IF;
END_FOR;
END_IF;
END_REGION
END_FUNCTION_BLOCK
Wie könnte ich hier einen dynamisch auftretenden Zugriffsfehler provozieren?
Im Rot markierten Vereich zähle ich den Index zwar vor ende nochmal hoch. Aber ich geh dann ja wieder in die while Prüfung und dürfte da dann direkt rausfallen.
Mir gehen da die Ideen etwas aus. Das ist übrigens ein Bibliotheksbaustein, der ist noch auf 20 weiteren exakt gleich konfigurierten CPUs drauf. Aber es passiert nur bei dieser einen.
Bevor ich jetzt Zeile für Zeile mit einem Dummymerker markiere um den exakten Ausprungspunkt und Zugriffsadresse rauszufinden, dache ich. Frag mal vielleicht hat einer ne iIee.