Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: SCL - ANY als Out-Parameter

  1. #1
    Registriert seit
    10.10.2008
    Beiträge
    43
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Leute,

    ich habe im Moment folgendes Problem: Ich habe einen Baustein gebaut, der anhand verschiedener Angaben einen ANY-Pointer baut:
    Code:
    FC240 : 
    
    Description
        
    
    Parameter
    000.0: ROOTNODE: STRUCT
    000.0:     IN: STRUCT
    000.0:         InDB: INT := 0 //DB-Nummer
    002.0:         InOffset: INT := 0 //Start-Byte
    004.0:         InLength: INT := 0 //Anzahl Bytes
    006.0:     OUT: STRUCT
    006.0:         OutAny: ANY
    016.0:     TEMP: STRUCT
    
    
    AWL-Code
    Netzwerk 1 : 
    
          L     P##OutAny
          LAR1  
          L     W#16#10       //SyntaxID. bei S7 immer 10
          T     B[AR1,P#0.0]
          L     W#16#2        //Typ BYTE
          T     B[AR1,P#1.0]
          L     #InLength     //Anzahl Bytes
          T     W[AR1,P#2.0]
          L     #InDB         //Quell-DB
          T     W[AR1,P#4.0]
          L     #InOffset     //Anfang der Quelle
          SLD   3
          T     D[AR1,P#6.0]
          L     B#16#84       //Speicherbereich (hier DB)
          T     B[AR1,P#6.0]
    Soweit so gut. Tut was es soll. Allerdings rufe ich diesen FC aus einem SCL-FC auf. Ich habe eine temporäre Variable tmpAny vom Typ ANY erstellt und rufe den Baustein bspw. folgendermaßen auf:
    Code:
    FC_GetAny(InDB := 1, InOffset := 4711, InLength := 12, OutAny := tmpAny);
    tmpAny soll nun eben auf die entsprechenden Daten im DB1 zeigen. Grund: Ich möchte im Anschluss den tmpAny an BLKMOV übergeben.

    Wenn ich mir allerdings den AWL-Code anschaue, der generiert wird, sieht dieser wie folgt aus:
    Code:
          L     #InPMFIFONum
          T     LW86
          L     LD72
          T     LD88
          L     LD76
          T     LD92
          L     LW80
          T     LW96
          UC    "FC_GetAny"
                P#V 86.0
                P#V 38.0
                P#V 34.0
                P#V 88.0
    Zur Erklärung der Adressen:
    V 86.0 = Wert von "InPMFIFONum"
    V 38.0 = tmpByteOffset
    V 34.0 = tmpLength
    V 88.0 = Wert von tmpAny

    Das heißt er kopiert erst den (leeren) tmpAny in ungenutzten Lokalspeicher und ruft damit dann FC_GetAny auf. Folglich liegen die Informationen, die GetAny schreibt, im Nirvana. Ein Rückübertragen in den echten tmpAny erfolgt nicht.

    Ich hatte auch schon getestet was passiert, wenn im FC_GetAny OutAny in INOUT deklariert ist: Kein Unterschied. *grummel*

    Gibt's hier irgendeinen Tipp wie ich die Ausgabe von FC_GetAny in tmpAny bekomme?

    Vielen Dank und viele Grüße
    Max
    Zitieren Zitieren SCL - ANY als Out-Parameter  

  2. #2
    Registriert seit
    10.10.2008
    Beiträge
    43
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Noch ein Nachtrag. Der Aufruf von FC_GetAny aus einem in AWL geschriebenen Baustein sieht bspw. so aus:
    Code:
          CALL  "FC_GetAny" (
                InDB     := #InFIFONr,
                InOffset := #InOffset,
                InLength := #InLen,
                OutAny   := P#V 16.0)
    An V 16.0 liegt tmpAny: ANY.

    *noch mehr grummel*

    Gruß
    Max

  3. #3
    Registriert seit
    29.03.2004
    Beiträge
    5.797
    Danke
    144
    Erhielt 1.707 Danke für 1.239 Beiträge

    Standard

    Problem umschiffen:
    Im SCL-Baustein eine AT-Sicht auf den Any machen, und die Werte direkt auf die Elemente der Sicht schreiben. Geht in SCL sehr komfortabel.

    Oder dein FC_GetAny gibt als Ausgangsparameter eine Struct zurück, die du mit der AT-Sicht aus dem SCL-Baustein verschalten müsstest. Bringt dann aber keinen wirklichen Gewinn an Übersichtlichkeit mehr (und der Baustein ist für den Aufruf aus AWL mehr oder weniger sinnlos.).

  4. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.314
    Danke
    932
    Erhielt 3.329 Danke für 2.688 Beiträge

    Standard

    Zitat Zitat von Löwensenft Beitrag anzeigen
    Code:
          L     P##OutAny
          LAR1  
          L     W#16#10       //SyntaxID. bei S7 immer 10
          T     B[AR1,P#0.0]
          L     W#16#2        //Typ BYTE
          T     B[AR1,P#1.0]
          L     #InLength     //Anzahl Bytes
          T     W[AR1,P#2.0]
          L     #InDB         //Quell-DB
          T     W[AR1,P#4.0]
          L     #InOffset     //Anfang der Quelle
          SLD   3
          T     D[AR1,P#6.0]
          L     B#16#84       //Speicherbereich (hier DB)
          T     B[AR1,P#6.0]
    Soweit so gut. Tut was es soll.
    Nicht gut. Tut es nicht.
    Über den Stack wird nicht der ANY übergeben, sondern ein Pointer (6 Byte, P#V88.0) auf eine ANY-Variable im TEMP des Aufrufers.
    "L P##OutAny" lädt nicht die Adresse des übergebenen ANY-Pointers sondern die Adresse des OUT-Parameters #OutAny.

    Du mußt Deinen ANY auf die Adresse schreiben, welche Du an der Adresse P##OutAny vorfindest.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  5. #5
    Registriert seit
    29.03.2004
    Beiträge
    5.797
    Danke
    144
    Erhielt 1.707 Danke für 1.239 Beiträge

    Standard

    @PN
    Es wird schon ein 10 Byte Any übergeben.
    Nur hat SCL eine andere Interpretation davon wozu ein Any-Pointer als Parameter verwendet werden soll. SCL geht wohl davon aus, dass ich den Any dereferenzieren möchte und nicht den Any an sich modifizieren. Das Dereferenzieren würde auch funktionieren wenn ich in tmpAny vorher einen gültigen Any eintrage.

  6. #6
    Registriert seit
    10.10.2008
    Beiträge
    43
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hi,

    ich konnte SCL halbwegs austricksen, indem ich eine AT-Sicht (tmpAnyAt) auf tmpAny erstellt habe und tmpAnyAt an GetAny übergeben habe. Dann wurde automatisch die Adresse von tmpAny in die Lokaldaten geschrieben, die dann an GetAny übergeben wurden...

    @PN/DP: Ich hatte auch schon überlegt, ob ich tatsächlich die Parameterübergabe und die Verwendung von L P##OutAny missverstanden habe. Aber wie Thomas richtigerweise schreibt interpretieren der AWL-Editor/Syntaxchecker(?) und der SCL-Compiler den ANY-Parameter unterschiedlich.

    Ich habe nun allerdings - da ich vermute, dass es hierzu keine einfache und schnelle Lösung gibt - tatsächlich die AT-Sicht verwendet und schreibe halt doch wieder manuell die Daten rein.

    Da kommt mir mal wieder die Frage hoch, ob es bei Siemens nicht zum guten Programmierstil dazugehört definierte Funktionen in eben solche zu verpacken. Ich will halt nicht ein und dieselbe Funktion zig mal in meinem Programm haben, wenn ich auch ne Funktion aufrufen kann, die genau das macht. Erhöht die Wartbarkeit minimalst. Naja, ich bin wohl doch ein verwöhnter Hochsprachenprogrammierer...

    Wenn dennoch jemand ne Idee hat, immer her damit. Gibt es eigentlich einen Third-Party-SCL-Compiler der gescheit ist? :P

    Grüße
    Max

  7. #7
    Registriert seit
    29.03.2004
    Beiträge
    5.797
    Danke
    144
    Erhielt 1.707 Danke für 1.239 Beiträge

    Standard

    Für meinen Geschmack ist das Verhalten des SCL Compilers logischer. So wie du das in AWL verwendest, ist eigentlich nicht das wozu ein Any-Pointer vorgesehen ist. Du musst da ja auch schon mit den Vorgänger Lokaldaten tricksen.

    Theoretisch könnte jemand deinen Baustein aus AWL heraus mit:

    CALL "FC_GetAny" (
    InDB := #InFIFONr,
    InOffset := #InOffset,
    InLength := #InLen,
    OutAny := P#DB1.DBX 200.0 BYTE 1000)

    aufrufen. Da kommt auch nichts sinnvolles bei heraus. So wird ein Any aber üblicherweise verwendet.

  8. #8
    Registriert seit
    10.10.2008
    Beiträge
    43
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hmhm. Auf der einen Seite gebe ich dir Recht. Auf der anderen Seite wiedersprichst du dir ja selbst. Denn wenn ich bspw. "P#DB1.DBX 200.0 BYTE 1000" übergebe will ich ja genau an die Daten, die dort stehen, bzw. diese verändern. Ebenso geht es mir mit meinem Aufruf von FC_GetAny. So wie es im AWL interpretiert wird, ist es genau das, was der Any-Pointer machen soll. Er zeigt auf den tmpAny, der von FC_GetAny aus mit P#V 16.0 erreichbar ist. Wieso nun SCL hier meint besonders intelligent zu sein, verstehe ich nicht...

    Gruß
    Max

  9. #9
    Registriert seit
    29.03.2004
    Beiträge
    5.797
    Danke
    144
    Erhielt 1.707 Danke für 1.239 Beiträge

    Standard

    Du wirst aber wohl nicht P#V 16.0 geschrieben haben, sondern:
    Code:
          CALL  "FC_GetAny"
           InDB    :=1
           InOffset:=4711
           InLength:=12
           OutAny  :=#tmpAny
    Wenn du den von dir erzeugten Any nun an deinem BLKMOV verwendest:
    Code:
          CALL  "BLKMOV"
           SRCBLK :=P#DB1.DBX 0.0 BYTE 10
           RET_VAL:=MW100
           DSTBLK :=#tmpAny
    gehst du auch davon aus, dass dieser den tmpAny dereferenziert, d.h. die 10 Bytes vom DB1 auf die Adresse kopiert auf die tmpAny zeigt, und nicht an der der Any liegt.

    Bei der Verwendung des Any-Pointers in SCL hast du nicht alle Möglichkeiten wie in AWL. Ich finde in diesem Beispiel ist das Verhalten zumindest nachvollziehbar wenn man darüber nachdenkt.

  10. #10
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von Thomas_v2.1 Beitrag anzeigen
    gehst du auch davon aus, dass dieser den tmpAny dereferenziert, d.h. die 10 Bytes vom DB1 auf die Adresse kopiert auf die tmpAny zeigt, und nicht an der der Any liegt.
    Nö, bin ich nicht ganz deiner Meinung.

    Wenn der Blockmove seinen Any dereferenziert muss er schließlich auch die Informationen (DB1/10Byte/etc.) aus der Speicherstelle wo der Any liegt auslesen.
    Die Kopierfunktion selbst erfolgt danach separat.
    Würde also auch nichts dagegen sprechen (sofern es die Sollfunktion wäre) dass Blockmove den Any bearbeitet. Ist bei Blockmove natürlich nicht der Fall.
    Ob man den Any an seinen FB/FC-Paramtern jetzt lesend-derefenziert oder schreibend-bearbeitet sollte eigentlich schon Aufgabe des FC/FB-Programmierers sein. Ich gehe eigentlich nicht grundsätzlich davon aus dass ein Any an einem FB/FC-Parameter nur dereferenziert wird.

    Generell ist der Unterschied zwischen AWL-Compiler und SCL-Compiler in dem Fall schon ordentlich. Da kann man schön auf die Nase fallen.
    Geändert von RONIN (31.03.2015 um 22:55 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

Ähnliche Themen

  1. ANY Pointer als In Parameter...
    Von haraldign im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 05.02.2016, 13:35
  2. ANY als Parameter in SCL
    Von Züttu im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 08.01.2013, 19:43
  3. UDT als FC-Parameter
    Von Reinhard.Steinbrueck im Forum Simatic
    Antworten: 13
    Letzter Beitrag: 15.07.2011, 18:01
  4. UDT als IN-Parameter am FB
    Von OB21 im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 15.08.2010, 17:14
  5. SCL - OB und Array als Parameter
    Von Bluescreener im Forum Hochsprachen - OPC
    Antworten: 1
    Letzter Beitrag: 15.02.2008, 15:21

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •