Step 7 String als Eingangsparameter in DB kopieren

Bretti

Level-1
Beiträge
14
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte einen String[32] in einen DB umkopieren.
Sowohl den String als auch den Zeiger auf den Zielbereich habe ich als Eingangspameter angelegt. Der Zeiger ist ebenfalls auf einen String[32].

Wenn ich mir nun den Zeiger in den TEMP-Bereich kopiere und anschließend die SFC20 zum Kopieren aufrufe, erhalte ich den Rückgabewert 16#8124 (Bereichsfehler beim Lesen eines Parameters).


Kann mir jemand sagen, was ich falsch mache?

Code:
FUNCTION_BLOCK FB 999
TITLE =
VERSION : 0.1


VAR_INPUT
  STR : STRING  [32 ];    
  P_ZIELBEREICH : ANY ;    
END_VAR
VAR_TEMP
  P_ANY : BOOL ;    
  TEMP_RETVAL : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =

      LAR1  P##P_ZIELBEREICH; 
      LAR2  P##P_ANY; 
//;
      L     D [AR1,P#0.0]; 
      T     D [AR2,P#0.0]; 
      L     D [AR1,P#4.0]; 
      T     D [AR2,P#4.0]; 
      L     W [AR1,P#8.0]; 
      T     W [AR2,P#8.0]; 
//;
      CALL SFC   20 (
           SRCBLK                   := #STR,
           RET_VAL                  := #TEMP_RETVAL,
           DSTBLK                   := #P_ANY);
END_FUNCTION_BLOCK


Vielen Dank im Voraus!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kleiner Fehler beim Herauslösen aus dem Projekt, habe ich korrigiert, das Fehlerbild ist das selbe. :(

Code:
FUNCTION_BLOCK FB 999
TITLE =
VERSION : 0.1


VAR_INPUT
  STR : STRING  [32 ];    
  P_ZIELBEREICH : ANY ;    
END_VAR
VAR_TEMP
  P_ANY : ANY ;    
  TEMP_RETVAL : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =

      LAR1  P##P_ZIELBEREICH; 
      LAR2  P##P_ANY; 
//;
      L     D [AR1,P#0.0]; 
      T     D [AR2,P#0.0]; 
      L     D [AR1,P#4.0]; 
      T     D [AR2,P#4.0]; 
      L     W [AR1,P#8.0]; 
      T     W [AR2,P#8.0]; 
//;
      CALL SFC   20 (
           SRCBLK                   := #STR,
           RET_VAL                  := #TEMP_RETVAL,
           DSTBLK                   := #P_ANY);
END_FUNCTION_BLOCK
 
Problem 1: Du zerstörst bei deinem multiinstanzfähingen FB das AR2 im Moment in dem du LAR2 schreibst. Alle STAT-Zugriffe die du nachdem machst gehen nicht mehr
Problem 2: Beim Kopieren des Pointers aus dem IN bekommst du die falsche Bereichskennung (DB) statt (IDB) - obwohl das nicht direkt einen Fehler verursacht

[EDIT]
Problem 3: Der Multiinstanzoffset wurde nirgens auffaddiert.

Sieh dir mal dazu die Vorlage von PN/DP an.
http://www.sps-forum.de/simatic/63603-any-pointer-ueber-bausteinschnittstelle-2.html#post481732
 
Zuletzt bearbeitet:
Machst du den Pointer von Hand an die Schnittstelle (P#DB10.dbx0.0 byte 34) oder Symbolisch auf das Stringsymbol?
Wenn von Hand dann stimmt die länge? also nicht die 2 zusätzlichen Bytes vergessen?

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zu Problem 1: Ich habe den FB in ein Test-Projekt (PLCSIM) kopiert, wo nur dieser eine FB aufgerufen wird, im originalen Programm sichere ich mir vorher AR1 und AR2.
Code:
      TAR1  #AR1_SICHERUNG
      TAR2  #AR2_SICHERUNG
Am Ende des FB's werden diese zurückgeladen
Code:
      LAR1  #AR1_SICHERUNG
      LAR2  #AR2_SICHERUNG

Zu Problem 2: Ich möchte ja in einen DB kopieren, damit sollte doch die Bereichskennung korrekt sein, oder?


@vollmi: Am Aufruf ist symbolisch. "DB_TEST".Daten.name (34 Byte)
 
Zuletzt bearbeitet:
Zu Problem 2: Ich möchte ja in einen DB kopieren, damit sollte doch die Bereichskennung korrekt sein, oder?
Nicht ganz. Zuerst willst du ja den ANY-Pointer aus dem IN-Bereich des FBs nach Temp kopieren (also aus dem Instanzdatenbaustein).
Es geht um die Bereichskennung wo du den ANY-Pointer her-kopierst. In den Datenwerten (10Byte) des Pointers steht dann schon wieder "DB" drin.

Da du im Moment aber nur einen Zeiger auf P_ZIELBEREICH in das AR1 lädst, stimmt die Bereichskennung dort noch mit IDB.
Im Moment kopierst du mittels bereichsübergreifender indirekter Adressierung aus dem IDB

Wenn du dann (gezwungenermaßen) den Multiinstanzoffset aus AR2 aufaddierst (fehlt bei dir im Moment noch) bekommst du vom AR2 die falsche Kennung die dann beim Aufaddieren +AR1 ins AR1 übernommen wird
Dass würde dann dazu führen, dass du mittels bereichsübergreifender indirekter Adressierung quasi einen Global-DB-Zugriff auf den DB mit der Nummer des Instanzdatenbausteins machen würdest..

Hoffe verständlich. Die Details findest du auch noch mal im Beitrag von PN/DP.
Funktioniert im Endeffekt auch ist aber nicht ganz sauber.

Fazit: Halte dich beim Kopieren von ANY-Pointern von IN nach TEMP in FBs einfach an die Vorlage von PN/DP, die berücksichtigt das schon.
 
Zuletzt bearbeitet:
KLAR dass das nicht geht! :rolleyes:
Am Ende des FB's werden diese zurückgeladen
Code:
      LAR1  #AR1_SICHERUNG
      LAR2  #AR2_SICHERUNG
Das machst du nicht am Ende des FB sondern direkt nach dem kopieren!
Das Problem ist ja, dass wenn du dein AR2 (Multiinstanzoffset) veränderst, du innerhalb des FB nicht mehr auf IN/OUT/STAT-Parameter zugreifen kannst, sondern irgendwo landest .

Wenn du das wiederherstellen des AR2 am Ende des FBs machst bringt dir das gar nix mehr!

Die Ursache für W#16#8124 (1 steht für Paramater 1 - SRCBLK) ist dann logischerweise auch dass der SFC20 keinen korrekten Zugriff auf den im IN-Bereich liegenden String bekommt.
Da das AR2 zu dem Zeitpunkt falsch ist!

Das nächste Problem ist: Der Multiinstanzoffset wurde nirgens auffaddiert.

So geht das was du vor hast problemlos...
Code:
FUNCTION_BLOCK FB 999
TITLE =
VERSION : 0.1

VAR_INPUT
  STR : STRING  [40 ];    
  P_ZIELBEREICH : ANY ;    
END_VAR
VAR_TEMP
  P_ANY : ANY ;    
  SaveAR2 : DWORD ;    
  iTMp : INT ;    
END_VAR

BEGIN
NETWORK
TITLE =

      TAR2  #SaveAR2; 

      L     P##P_ZIELBEREICH;    [COLOR=#0000ff]// relative Adresse #P_ZIELBEREICH in dieser Instanz (DI) [/COLOR]
      [COLOR=#ff0000][B]L     #SaveAR2;[/B][/COLOR]        [COLOR=#0000ff]// Offset dieser Multiinstanz (DB)[/COLOR]
      [B][COLOR=#ff0000]UD    DW#16#FFFFFF;[/COLOR][/B]    [COLOR=#0000ff]// Bereichskennung (DB) die von AR2 mitkommt ausblenden[/COLOR]
[COLOR=#ff0000][B]     +D    ; [/B][/COLOR]
      LAR1  ;            [COLOR=#0000ff]// AR1: absolute Adresse #P_ZIELBEREICH im IDB (DI)[/COLOR]
      LAR2  P##P_ANY; 

      L     DID [AR1,P#0.0]; 
      T     LD [AR2,P#0.0]; 
      L     DIW [AR1,P#4.0]; 
      T     LW [AR2,P#4.0]; 
      L     DID [AR1,P#6.0]; 
      T     LD [AR2,P#6.0]; 

[COLOR=#ff0000][B]      LAR2  #SaveAR2; [/B][/COLOR]

      CALL "BLKMOV" (
           SRCBLK   := #STR,
           RET_VAL  := #iTMp,
           DSTBLK   := #P_ANY);
      NOP   0; 

END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Danke, RONIN!!!

Kann ich das so verstehen, dass ich, wenn ich einen Pointer nach TEMP umkopieren will, immer dieser Methodik anwenden muss?
In einem FB ja, nur dort hat man das Problem mit dem Multiinstanz-Offset und einem Instanzdatenbaustein wo man herkopiert.

Für einen FC hätte den Eingangsversuch schon gepasst da es diesen Offset dort nicht gibt und da du dir dort das AR2 eigentlich auch nicht zerstören kannst.
Man kann sich dort also auch das Retten des AR2 sparen.
Beispiel ANY-Pointer aus FC-IN nach Temp kopieren

Noch was zum Unterschied bei der Übergabe von Any-Pointern zwischen FB und FC:
FB: Dort bekommt man den ANY quasi perValue über den IDB in den IN-Bereich übergeben. Der ANY-Pointer wird also tatsächlich im IDB abgelegt.
FC: Dort bekommt man einen 6-Byte Pointer (quasi perReference) auf den Lokaldaten-Bereich des Bausteins der Den FC aufruft.
Dieser legt nämlich dort den ANY-Pointer, den man als Parameter angegeben hat, ab. Der FC hat je keinen Speicherbereich um etwas entgegen zu nehmen....​

Hoffe bei dem ganzen Gewirr war jetzt kein Blödsinn dabei...
 
Zuletzt bearbeitet:
Aber schon krass auf was man bei AWL alles achten muss. Bei SCL sieht das so einfach aus.
Code:
FUNCTION_BLOCK FB999


TITLE = 'ANY_Test'




VERSION : '1.8'
AUTHOR  : t
NAME    : t
FAMILY  : t


VAR_INPUT
  STR : STRING[40];    
    P_ZIELBEREICH : ANY ;    
END_VAR
VAR_TEMP
  P_ANY : ANY ;   
  iTMp : INT ;  
END_VAR
                   
P_ANY := P_ZIELBEREICH;


iTMp := BLKMOV(SRCBLK := STR // IN: ANY
       ,DSTBLK := P_Any // OUT: ANY
       ); // INT


END_FUNCTION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jep, ist definitiv unpraktisch. Klarer Vorteil SCL sobald Strukturierte Datentypen (z.B. Strings) ins Spiel kommen.
Meistens wenn's in die Richtung oder Array-Indizes geht, nehm ich dann auch SCL.

Ohne jetzt genau den Code zu kennen den der SCL-Compiler draus macht, bin mir sicher irgendwer hier hat das schon mal untersucht, wird aber wahrscheinlich ziemlich das selbe rauskommen.

Strukturierte Datentypen übergeben ist eine Krux. Vor allem auf den Teil mit der Bereichskennung in AR2 hab ich irgendwann von PN/DP mitbekommen. Da hab ich nicht schlecht gestaunt.
Daher immer schön an die Kopiervorlage halten. :cool:
 
Zuletzt bearbeitet:
Da wird dann sowas draus. Etwas mehr code als bei deiner optimierung.
Obs viel mehr zykluszeit braucht kann ich aber nicht schätzen.
Code:
FUNCTION_BLOCK "testen"
TITLE =ANY_Test
AUTHOR : VoR
FAMILY : TUV
NAME : AV
VERSION : 1.8




VAR_INPUT
  STR : STRING  [40 ];	
  P_ZIELBEREICH : ANY ;	
END_VAR
VAR_TEMP
  P_ANY : ANY ;	
  iTMp : INT ;	
END_VAR
BEGIN
NETWORK
TITLE =SCL Netzwerk
//generiert vom SCL Übersetzer Version:  SCLCOMP K05.03.08.01_01.04.00.03 release
      SET   ; 
      SAVE  ; 
      =     L     12.1; 
      L     DID [AR2,P#42.0]; 
      T     LD     0; 
      L     DID [AR2,P#46.0]; 
      T     LD     4; 
      L     DIW [AR2,P#50.0]; 
      T     LW     8; 
      L     DW#16#10130001; 
      T     LD    14; 
      L     DINO; 
      T     LW    18; 
      TAR2  ; 
      +     L#0; 
      T     LD    20; 
      L     LD     0; 
      T     LD    24; 
      L     LD     4; 
      T     LD    28; 
      L     LW     8; 
      T     LW    32; 
      TAR2  LD    34; 
      UC    "BLKMOV" {
            P#L 14.0,
            P#L 10.0,
            P#L 24.0};
      LAR2  LD    34;
      L     #iTMp; 
      U     L     12.1; 
      SAVE  ; 
      BE    ; 
END_FUNCTION_BLOCK
 
Hmm.. sieht interessant aus. Muss ich mal in ner freien Minute anschauen was da passiert. Danke.
 
Zurück
Oben