TIA Speicherverwaltung bei Übergabe in InOut eines FB.

Aksels

Level-2
Beiträge
257
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Liebe Mitleser,

wenn man in neueren TIA-Versionen eine Variable zum Beispiel int als InOut in einem FB anlegt kann man ja extern eine Variable anlegen, die im Baustein auch geschrieben werden kann.
Man kann aber die externe Beschaltung unterlassen und mit der InOut-Variablen arbeiten, die sogar remanent geschaltet werden kann.
Wie sieht das mit dem Speicherplatz aus. Wird beim externen Anlegen die Variable auf die interne kopiert und beim Verlassen wieder zurück, so dass die interne, wie die externe Platz verbrauchen?
Ich habe nämlich Speicherplatzprobleme und vermute, es liegt daran, dass ich große Structs (mit Strings die ich bereits kürzen musste) über InOut übergebe.
Wenn dieses Struct dann doppelt Speicher verbraucht, muss ich das anders programmieren (input und output sachen in separate Structs, die ich im Input und Output Teil des FBs übergebe). Ich vermute da ist es dann das gleiche Problem, aber ich kann viele Daten weglassen.
Oder kann ich irgendwie nur einen Zeiger auf die Daten übergeben, so dass der Speicher nicht nochmal im FB reserviert werden muss?
 
Was hast Du denn für eine CPU?
Ist der FB "optimiert" oder Standard-Zugriff? Ist die außen angeschaltete Variable in "optimiertem" oder Standardzugriff-Speicher? Ist der InOut-Parameter eine Struktur oder ein einfacher Datentyp?
Danach richtet sich, ob der InOut als Referenz (Call-by-reference) oder als Kopie (Call-by-value) übergeben wird.

Wie groß sind die FB-Instanzen bzw. der/die IDB? Daran kann man sehen, ob in der Instanz Speicherplatz für die Parameter-Kopie verbraucht wird.

Programmierleitfaden für S7-1200/S7-1500

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Bausteine sollen auf 1200ern und 1500ern laufen. Ich habe darauf nur geringen Einfluss, da meine Planer in den Kundenfirmen sich nach den Ausschreibungen richten.
Bausteinzugriff ist bei diesen Bausteinen optimiert. Also sowohl der aussenliegende Struct, als auch der InOut.
Länge des FB mit InOut Struct: Ladespeicher: 95407 Bytes Arbeitsspeicher: 7573 Bytes
Länge des IDB mit InOut Struct: Ladespeicher: 7511 Bytes Arbeitsspeicher: 2248 Bytes
Länge des FB mit StaticStruct: Ladespeicher: 45561 Bytes Arbeitsspeicher: 4657 Bytes
Länge des IDB mit Static Struct: Ladespeicher: 37901 Bytes Arbeitsspeicher: 34670 Bytes


Struct:
Code:
TYPE "DT_Fehler_Sammel_Einzel_1"
VERSION : 0.1
   STRUCT
      Nr : Array[0..15] of Struct
         I_Fehler : Bool;
         I_Betrieb : Bool;
         O_Meldelampe_Betrieb : Bool;
         O_Meldelampe_Stoerung : Bool;
         O_Flowchief_Fehler : Bool;
         S_Fehler_Unquittiert : Bool;
         S_Flanke : Bool;
         s_Fl_Sek_Imp : Bool;
         s_Fl_Sek_Imp2 : Bool;
         s_Text_Stoer : String["c_Fehler_String_Laenge"] := 'Nicht projektiert.';
         s_Text_Betrieb : String["c_Fehler_String_Laenge"] := 'Nicht projektiert.';
      END_STRUCT;
      I_Quitt : Bool;
      I_Quitt_Hupe : Bool;
      I_Anwesend : Bool;
      I_Lampentest : Bool;
      S_Err_Qu_Zu_HMI_A : Word;
      S_Err_Qu_Zu_HMI_B : Word;
      S_Quitt_Von_HMI : Word;
      S_Betr_Meld_Zu_HMI : Word;
      s_Grp : Int := 0;
      s_Grp_Anz_Fehler : Int;
      s_Grp_Anz_Fehler_UQ : Int;
      O_SaSt_Grp_ML : Bool;
      O_SaSt_Grp_UQ_Kein : Bool;
      O_SaSt_Grp_Kein : Bool;
   END_STRUCT;

END_TYPE
 
Zuletzt bearbeitet:
Also wenn der Datentyp (die Struktur) als Static-Struct mehr als 30kB Arbeitsspeicher braucht, der IDB mit InOut des selben Datentyps aber nur ca. 2000 Bytes Arbeitsspeicher braucht, dann ist die Übergabe als Referenz.

:confused: Ist das der Datentyp "DT_Fehler_Sammel_Einzel_1" der mehr als 30kB braucht?? Wie lang sind denn die Strings deklariert?

Harald
 
Ach ja, die Strings. Die Konstante hat den Wert 64.
Ich muss Dir noch Infos liefern:
Der DT_Fehler_Sammel_Einzel wird übergeben in den InOut.
Dieser Struct wird im Static benuzt:
Code:
TYPE "DT_Fehler_Sammel"
VERSION : 0.1
   STRUCT
      FNr : Array[0..15] of Struct
         Bit : "DT_Fehler_Sammel_Einzel";
      END_STRUCT;
   END_STRUCT;

END_TYPE
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo lieber Leser,
nach vielem Hin- und Herüberlegen bin ich zu dem Schluss gekommen, dass man um globale Zugriffe nicht drum herum kommt um Speicher zu sparen. Das Problem ist, wenn man Structs als IO übergibt verbraucht man immer den Speicher des Structs im ursprünglichen DB. Zusätzlich den gleichen Speicherplatz nochmal im IO-Bereich des FBs. Wenn man direkt auf den DB zugreift bekommt man zwar die Meldung beim Typisieren für eine Bibliothek (Warnung wegen globalem Zugriff) spart aber den Speicher.
Gruß,
Aksels
 
Das Problem ist, wenn man Structs als IO übergibt verbraucht man immer den Speicher des Structs im ursprünglichen DB. Zusätzlich den gleichen Speicherplatz nochmal im IO-Bereich des FBs.
Im IO-Bereich des FB wird nur Speicher belegt, wenn Structs byValue übergeben werden. Gerade um Speicherplatz zu sparen werden Structs via IN_OUT normalerweise byReference übergeben und benötigen nur einen Pointer im Stack. siehe nochmal den von mir in #2 verlinkten Programmierleitfaden

Harald
 
Guten Morgen Harald.
Hmmmm..... da ich in dem Baustein ein WORD an das HMI für HMI-Meldungen übergebe ist der Baustein nicht optimiert. Oder ist das nicht mehr notwendig?
Gruß,
Aksels
 
Zuviel Werbung?
-> Hier kostenlos registrieren
wenn der Baustein nicht optimiert ist und der DB optimiert oder umgekehrt ist die Übergabe "CopyByValue" --> echte Kopie der Daten
von Optimiert nach nicht optimiert ist das immer so egal ob DB-DB / DB-FB ......
 
Zurück
Oben