Codeverständnis

mitchih

Level-2
Beiträge
806
Reaktionspunkte
32
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
auf einer S7-300 (317-F2DP)
habe ich folgenden Code gefunden, Leider ist das ganze für mich etwas unverständlich. Hier zuerst mal der Code des FB:(Kommentare stammen von mir)

Code:
NW1:
 
[FONT=Calibri][SIZE=3]  TAR1  #Register_AR1      /AR1 sichern  
[/SIZE][SIZE=3]  TAR2  #Register_AR2     /AR 2 sichern[/SIZE]
[SIZE=3]L     P##ExPositionsdaten  /In Variable (P#Db511.dbx0.0)  (Positionen laden)
[/SIZE][SIZE=3]LAR1                                  // Pointer nach AR1 schieben
[/SIZE][SIZE=3] L     P##Adr_Positionsdaten // woher kommt dieser Pointer (Temp Variable)
[/SIZE][SIZE=3]LAR2                                     // Pointer nach AR 2 (Zeiger wohin??)[/SIZE]
[/FONT] 
[SIZE=3][FONT=Calibri]L     D [AR1,P#0.0          // Auf Welche Lokalworte wird von Wo geschrieben
[/FONT][/SIZE][SIZE=3][FONT=Calibri]T     LD [AR2,P#0.0]        
[/FONT][/SIZE][SIZE=3][FONT=Calibri] L     D [AR1,P#4.0]
[/FONT][/SIZE][SIZE=3][FONT=Calibri]T     LD [AR2,P#4.0]
[/FONT][/SIZE][SIZE=3][FONT=Calibri]L     W [AR1,P#8.0]
[/FONT][/SIZE][SIZE=3][FONT=Calibri]T     LW [AR2,P#8.0][/FONT][/SIZE]
[SIZE=3][FONT=Calibri] LAR1  #Register_AR1    //Adressregister zurücksichern[/FONT][/SIZE]
[SIZE=3][FONT=Calibri] LAR2  #Register_AR2    //Adressregister zurücksichern[/FONT][/SIZE]
[FONT=Calibri][SIZE=3] [/SIZE][/FONT]
[FONT=Calibri][SIZE=3]NW 2: [/SIZE][/FONT]
[SIZE=3][FONT=Calibri]   CALL  "BLKMOV" // SFC 20
[/FONT][/SIZE][SIZE=3][FONT=Calibri]   SRCBLK :=#Adr_Positionsdaten   // Woher kommt der Pointer AR wurde ja zurückgeschrieben
[/FONT][/SIZE][SIZE=3][FONT=Calibri]   RET_VAL:=#Hilfswort_INT
[/FONT][/SIZE][SIZE=3][FONT=Calibri]   DSTBLK :=#Positionen  //Ziel Struct innerhalb des Stat Bereichs des FB[/FONT][/SIZE]

Problem, bei den Positionen gibt es keine Reserve, ich muss aber ca. 10 Positionen erweitern (DINT) Momentan sind 7 Vorhanden.
Ich würde jetzt hingehen und den DB511 (Ex Psotionsdaten erweitern) sowie den Struct, wie stelle ich jedoch sicher das die Positionsdaten auch korrekt kopiert werden??

Vielen Dank für eure Hilfe
 
Hallo Mitch,
die beiden Bezeichner, die du da erwähnst muß es in deinem Baustein geben - z.B. als Name einer Variablen, eines Array's oder einer Struktur. Das kann ein IN-Parameter sein oder etwas aus dem TEMP- oder STAT-Bereich. Zeig' doch ggf. mal deinen Bausteinkopf ...

Gruß
Larry

Ach ja - wegen NW2:
Der Bezeichner benötigt da das AR-Register nicht mehr, da er dort ja schon als Pointer angesehen wird ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich das richtig sehe wird da die Adresse des In-Parameters ExPositionsdaten auf die TempVariable Adr_Positionsdaten umkopiert, welche wohl als Any deklariert ist. Der Any wird dann an den SFC20 angelegt. Denn ExPositionsdaten kann man nicht direkt an den SFC20 legen, dieser verlangt eine Any als IN! Du kannst den DB sicherlich erweitern, denn an den FB wird ja direkt die Position angelegt. (wenn da eine Längen und Typangabe dabei ist). Oder Aber da wird eine Struct angelegt, da diese als Any-Pointer übergeben wird ist dann vielleicht die Längeninformation auch enthalten!
 
Zuletzt bearbeitet:
Der FB hat einen Eingangsparameter "ExPositionsdaten" vom Typ Any (10 Byte großer Pointer).
Der FB soll nun einen Datenbereich, der über "ExPositionsdaten" angegeben ist, in den Struct
"Positionen" in der FB-Instanz kopieren.

Da man am SFC20 den IN-Parameter "ExPositionsdaten" nicht direkt angeben kann, wird der Any-Pointer
aus dem IN-Parameter "ExPositionsdaten" zunächst auf einen zweiten Any-Pointer "Adr_Positionsdaten"
im Lokaldatenbereich (TEMP) umkopiert und danach am SFC20 diese lokale Pointer-Kopie an SRCBLK angegeben.

Für das indirekte Umkopieren vom IN-Parameter auf den TEMP-Any-Pointer werden AR1 und AR2 benutzt.
AR1 zeigt auf den IN-Parameter "ExPositionsdaten" (3./4.Zeile: L P##ExPositionsdaten / LAR1).
AR2 zeigt auf den TEMP-Any-Pointer "Adr_Positionsdaten" (5./6.Zeile: L P##Adr_Positionsdaten / LAR2).

Harald
 
Hallo Mitch,
die beiden Bezeichner, die du da erwähnst muß es in deinem Baustein geben - z.B. als Name einer Variablen, eines Array's oder einer Struktur. Das kann ein IN-Parameter sein oder etwas aus dem TEMP- oder STAT-Bereich. Zeig' doch ggf. mal deinen Bausteinkopf ...

Gruß
Larry

Ach ja - wegen NW2:
Der Bezeichner benötigt da das AR-Register nicht mehr, da er dort ja schon als Pointer angesehen wird ...

Also Ex Positionsdaten ist ein In Parameter und Adr_Positionsdaten ein Temp vom Typ Any.
Leider verstehe ich halt das Lade transferieren nicht, wird dort der 2. Pointer erzeugt?? bzw. was geschieht dort.

Das das umkopieren in einen Struct Stattfindet ist richtig. Nur woher hat die S7 bzw. der SFC 20 die Länge des umzukopierenden Bereichs?? (Längenangabe fehlt beim Pointer) über den Struct??
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

...Problem, bei den Positionen gibt es keine Reserve, ich muss aber ca. 10 Positionen erweitern (DINT) Momentan sind 7 Vorhanden.
Ich würde jetzt hingehen und den DB511 (Ex Psotionsdaten erweitern) sowie den Struct, wie stelle ich jedoch sicher das die Positionsdaten auch korrekt kopiert werden??...

erweitern ist richtig, beide Bereiche müssen die selbe Länge haben, da es sich um einen 10 Byte Pointer handelt muss der Pointer am IN folgendermaßen geschrieben werden: z.B. P#DB511.DBX0.0 BYTE 30 (30 Bytes ab Adresse 0.0). Der Zielbereich in Deinem FB muss natürlich genau so lang sein.;)

Gruss Daniel
 
Leider verstehe ich halt das Lade transferieren nicht, wird dort der 2. Pointer erzeugt?? bzw. was geschieht dort.
Du hast einen FB8, der Instanz-DB dafür könnte z.B. so aussehen:
(IN)
DBB0 ExPositionsdaten ANY
DBB10 ...
...
(STAT)
DBB30 Positionen STRUCT
...


Und Du hast den Lokaldatenbereich TEMP, der sieht z.B. so aus:
0.0 Register_AR1 DWORD
4.0 Register_AR2 DWORD
8.0 Adr_Positionsdaten ANY
18.0 ...


Im Programm läuft folgendes ab:
Code:
// Adressen der Pointervariablen in Adressregister laden

L     P##ExPositionsdaten    // lade die Adresse von IN:ExPositionsdaten (ab DBB0)
LAR1                         // AR1 enthält nun: P#DBX0.0

L     P##Adr_Positionsdaten  // lade die Adresse von TEMP:Adr_Positionsdaten (ab LB8)
LAR2                         // AR2 enthält nun: P#8.0

// Inhalt aus Quellvariable IN:ExPositionsdaten (DBB0..DBB9)
// indirekt in Zielvariable TEMP:Adr_Positionsdaten (LB8..LB17) kopieren

L     D [AR1,P#0.0]          // lade den Inhalt von DBB0..DBB3
T     LD [AR2,P#0.0]         // und speichere in LB8..LB11

L     D [AR1,P#4.0]          // lade den Inhalt von DBB4..DBB7
T     LD [AR2,P#4.0]         // und speichere in LB12..LB15

L     W [AR1,P#8.0]          // lade den Inhalt von DBB8..DBB9
T     LW [AR2,P#8.0]         // und speichere in LB16..LB17
Nun ist der Inhalt des Any-Pointers TEMP:Adr_Positionsdaten = Inhalt von IN:ExPositionsdaten, sie zeigen also auf den selben Bereich.
TEMP:Adr_Positionsdaten kann nun am SFC20 statt IN:ExPositionsdaten am SRCBLK verwendet werden.

Das kann man übrigens mit PLCSIM sehr gut beobachten (wenn der Baustein länger als nur 1 Zyklus aufgerufen wird).

Nur woher hat die S7 bzw. der SFC 20 die Länge des umzukopierenden Bereichs?? (Längenangabe fehlt beim Pointer)
Wie kommst Du zu der Annahme, daß die Längenangabe fehlt?
Ein Any-Pointer hat IMMER eine Längenangabe (die kann allerdings tatsächlich auch "BYTE 0" lauten).

Bei DSTBLK:=#Positionen steckt die Längenangabe in der bekannten Länge des Structs "Positionen" im STAT-Bereich.
(der Editor zeigt die Länge nur nicht extra an)
Bei SRCBLK:=#Adr_Positionsdaten kennt der Editor die Längenangabe nicht, da der Pointer ja erst zur Laufzeit übergeben wird.
Aber an der Aufrufstelle des FB8 wird höchstwahrscheinlich eine konstante Bereichsadresse an "ExPositionsdaten" übergeben.

Wenn an einen Baustein-Übergabeparameter vom Typ Any ein Bereich nicht absolut (z.B. P#DB511.DBX0.0 BYTE 70) sondern symbolisch
(z.B. "Regale".Positionen) übergeben wird, dann zeigt Step7 in der Symbolbeschreibung die Längenangabe nicht als "...BYTE 70" an,
sondern als "Zugriffsbreite: 70 Byte".

Gehe mal auf den Aufruf Deines FB8 und halte den Mauszeiger über den Aktualparameter, der an "ExPositionsdaten" dransteht.
Was steht in dem dann erscheinenden kleinen Tooltip? -> P#DB511.DBX0.0 / Zugriffsbreite: ... Byte

Harald
 
Zurück
Oben