Step 7 SCL - Auf Ziel eines ANY-Pointers zugreifen

Löwensenft

Level-1
Beiträge
43
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

mich plagt zur Zeit folgendes Problem: Ich schreibe einen FC mit einem IN-Parameter vom Typ ANY. Nun möchte ich auf den Wert, auf den der Pointer zeigt, zugreifen. Ich weiß im Moment aber absolut nicht, wie ich an den tatsächlichen Wert komme. Ich hatte ja auf eine Art Dereferenzierungs-Operanden (wie der * in C) gehofft, allerdings scheint es sowas "einfaches" nicht zu geben?

Grund für die Verwendung des ANY-Pointers ist, dass ich beliebige (eigentlich nur WORD, DWORD, INT oder DINT) Werte annehmen können möchte, aber nicht vier einzelne IN-Parameter anbieten möchte. Eine Verwendung des Typs DWORD oder DINT als Eingangsparameter-Typ ist auch nicht machbar, da ich je nach Typ eine andere Teilfunktion ausführen muss. Über das Datentyp-Byte im ANY-Pointer kann ich ja herausbekommen, was es für ein Datentyp ist. Also "was" übergeben wird ist bekannt. Dennoch: WIE komme ich an die Daten dran? ;)

Auch in AWL scheint der Zugriff auf die Daten auf die ein ANY-Pointer zeigt nicht allzu einfach. Um zielführende Tipps bin ich sehr dankbar, auch wenn es in SCL nicht gehen sollte, dafür aber in AWL! :)

Grüße
Max
 
Hallo,
du mußt da wie folgt vorgehen :
- du legst dir eine TEMP-Variable vom Typ ANY an.
- auf diese Variable weisst du deine IN-Variable vom Typ ANY zu
- auf diese TEMP-Variable legst du eine AT-Sicht, in der der Struktur-Aufbau des ANY-Pointers abgebildet wird
- nun schlüsselst du die Einzel-Elemente dieser Sicht auf und bildest dir daraus die Adresse und die Bit-Nummer der Speicher-Adresse
- des Weiteren ermittelst du den Typ (E, A, M , DB) und baust dir darauf bezogen die indirekte Adressierung auf.
- nun könntest du auf den Inhalt deiner übergebenen Variablen zugreifen

Es geht in SCL, das zu machen - ist aber deutlich oversized. Dieser Teil ist doch eher für AWL gedacht ... aber es geht natürlich ...

Gruß
Larry
 
Hi,

@Larry Laffer: äh ja *dump*, natürlich. Für E, A, M und DB komme ich so mit jeweils eingenen Zugriffen dran. Was ist aber mit ANY-Pointer auf Lokaldaten des aufrufenden Bausteins (was ja dann die "vorherigen Lokaldaten" sind)?

@JSEngineering: Danke für den Link. Sieht interessant aus.

Noch eine Info: Mir geht es hauptsächlich um das LESEN der Daten auf die der ANY-Pointer zeigt.

Gruß
Max
 
Hallo Max,
da SCL den Adress-Typ "L" und "LV" nicht kennt wird das problematisch - soll heissen : geht nicht.
Auch ein Blockmove auf deinen internen Speicher käme so nicht mehr in Frage, da durch das Umkopieren schon aus "L" dann "LV" würde und aus "LV" dann "LVV" (und den Typ gibt es ja gar nicht).

Aus deiner Antwort schliesse ich, dass du in der Sache nicht mehr ganz am Anfang stehst.
Du wirst also auf alle Fälle da etwas beschränken müssen :( - oder auf AWL zurückgehen :(

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

*seufz* mit so einer Antwort habe ich ja schon gerechnet. Ich frage mich immer wieder *warum* in der Siemens-Programmier-Welt vieles anders und einiges komplizierter ist als in der restlichen Programmier-Welt. Off-Topic: Hat sich denn in Richtung TIA dahingehend etwas getan?

Grüße
Max
 
Naja, Pointer (Hochsprache) sind nun einmal eigentlich nicht für Steuerungen gemacht.
In CoDeSys habe ich nicht einmal einen ANY-Pointer...
Ich seh es aber auch immer pragmatisch von der anderen Seite: Mit Pointern kann man ganz schnell viel kaputt machen und andere verwirren.
Wenn man versucht, es ohne Pointer hinzubekommen, ist es meinstens hinterher verständlicher - und fehlerfreier.
Und sonst mußt Du eben näher an die Hardware gehen, wie Larry schon sagt: AWL...Man
kann darüber geteilter Meinung sein...
 
Ja, wenn man mit Pointern arbeitet muss man immer wissen, was man tut. Eine SPS ist im Innern auch "nur" ein Rechner, der Maschinencode verarbeitet. AWL ist im Grunde nichts anderes als gepimpter und teilweise vereinfachter Assembler-Code. Dennoch kann man da nicht alles machen wie man es von "normalem Assembler" annehmen kann.

Auf der anderen Seite kann man sagen, dass jede absolute Adressierung in einem (SPS-)Programm an für sich ein einziges Gepointere ist. Denn ohne (Typ-)Kontrolle durch einen Compiler/Linker kann man da auch ganz schnell ganz viel kaputtschießen. Und das geht meiner Meinung nach in einem SPS-Programm wesentlich einfacher als in einem C-Programm.

Die Tatsache, dass im Pointer hinterlegt ist, was denn für ein Typ referenziert ist und welche Menge von Daten, finde ich gar nicht so verkehrt. Entsprechend kann man sein Programm "sicher" machen. Warum man nun nicht über "legale Wege" an alle referenzierten Daten kommt, ist mir jedoch wieder schleierhaft. Mir kommt da die Umsetzung der SCL/AWL-Sprachen teilweise recht inkonsequent vor. Aber das ist wirklich arg weit Off-Topic. ;)

Ich danke euch auf jeden Fall für die Ideen und Kommentare. Falls doch noch eine Info aufkommen sollte, wie man auf referenzierte Lokaldaten zugreifen kann, freue ich mich darüber. :)

Viele Grüße
Max
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Max,
du siehst das m.E. "ein bißchen" falsch.
Es war zuerst AWL da und irgendwann ganz viel später hatte man dann SCL "gebaut". In AWL könntest du den Pointer-Teil des ANY's direkt als Adresse weiterverwenden (über das AR-Register). Du müßtest nur schauen, ob es einen DB gibt und wenn ja den aufrufen - fertig.
SCL ist mehr dafür geschaffen, mit seinen eigenen Variablen herumzumachen.
Wenn man das berücksichtigt ist es eigentlich ganz einfach.
Ich verstehe aber deine Intension - ich hatte auch schon mal über etwas in der Art nachgedacht - es aber dann verworfen weil man an der Schnittstelle eines Bausteins schon durchaus den erwarteten Typ festlegen kann - das machen die meißten Hochsprachen ja auch nicht anders. Wenn man eine Überlagerung erzeugen könnte ...

Aber naja ... es ist halt wie es ist ...

Gruß
Larry
 
Aber kann bei einem Any-IN nicht nur auf die Adresse (LAR1 p##Any_Eingang) zugegriffen werden, oder ist das in SCL anderst, die Bereichslänge müsste seperat übergeben werden,
und man hat keine Informationen über die Struktur.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Grund für die Verwendung des ANY-Pointers ist, dass ich beliebige (eigentlich nur WORD, DWORD, INT oder DINT) Werte annehmen können möchte, aber nicht vier einzelne IN-Parameter anbieten möchte. Eine Verwendung des Typs DWORD oder DINT als Eingangsparameter-Typ ist auch nicht machbar, da ich je nach Typ eine andere Teilfunktion ausführen muss.
Wenn der FC sowieso verschiedene Dinge tun soll - warum mußt Du das alles in nur 1 FC quetschen?
Mache doch 4 FC mit jeweils verschiedenen Eingangsparametern.
Oder "wrappe" 4 FC um einen Kern-FC.

Allerdings könnte es passieren, daß solch ein Konstrukt womöglich jeder versteht... ;)

Harald
 
Oder nimm einen FB, da braucht man nicht alle Eingänge beschalten, und die nicht beschalteten braucht man bei Aufruf aus SCL auch nicht angeben. Gib dem FB noch einen "Mode"-Eingang und übergebe 1, 2, 3 oder 4, damit der Baustein weiß, welchen Eingangsparameter er auswerten soll.

Harald
 
Bei einem FC erhältst du hier einen Pointer, den angibt, wo die Daten des ANY-Pointers stehen. Da ist dann auch wieder die Bereichslänge mit drin.
... wo sollte die (in einem ANY) auch herkommen ... die Struktur ist ja eine willkürliche Vereinbarung ...

Gruß
Larry
aber nur wenn der Any-Pointer im V-Temp Bereich angelegt ist, wenn man außen (als IN-Parameter) eine beliebige struct_Var anliegt, hat man dann nur Zugriff mit deinem normalen Pointer (4 Byte) ?
 
@Michael:
Du hast Recht - da hatte ich mich vertan. Ich habe den Beitrag geändert.
Wo hattest du denn ein Problem mit den ANY's, worauf du dich bezogen hattest ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich wollte mit einem Baustein ermitteln ob in einer Struktur ein Bit 1 ist oder Bits zählen, könnte man anstatt dem Any-Pointer im V-Temp Bereich, auch eine Struct tempVar als Eingangsparameter verwenden, beim SFC20 BLCKMOVE muß man auch nichts im Temp-Bereich anlegen, aber ist ja auch eine SFC.
 
Zuletzt bearbeitet:
@Michael:
Du schmeisst hier (glaube ich) ein paar Dinge durcheinander.
Das mit dem "im TEMP-Bereich ablegen" ist notwendig wenn du innerhalb von SCL eine AT-Sicht auf den IN- oder IN-OUT-Parameter eines FC's machen willst - Fokus ist hier aber SCL.
Das Durchsuchen nach einem gesetzten Bit eines (wie auch immer gearteten) Bereichs ist mit dem ANY auf jeden Fall realisierbar - der ANY hätte hier ja alle dafür benötigten Daten.
Ist das noch ein Thema für dich ?

Gruß
Larry
 
@Larry
ist zwar nicht SCL aber zum Verständniss, wäre das so richtig:
Code:
  L     P##Struct_Any               //Eingang
      LAR1  

// Aufbau des ANY-Zeigers
      L     LW [AR1,P#2.0]
      T     #Anzahl_Bytes

      L     LW [AR1,P#4.0]
      T     #DB_Nr

      L     LD [AR1,P#6.0]              //Bereichszeiger
      LAR1  

      AUF   DB [#DB_Nr]
      L     0
      T     #Loop_Zaehler

next: NOP   0
      L     #Loop_Zaehler
      SLW   3
      +AR1  
      L     B [AR1,P#0.0]
      L     0
      >I    
      =     #Bit_True

      L     #Loop_Zaehler
      +     1
      U(    
      T     #Loop_Zaehler
      L     #Anzahl_Bytes
      >I    
      )     
      O     #Bit_True
      SPB   exit
      SPA   next
exit: NOP   0
 
Zuletzt bearbeitet:
Zurück
Oben