S7 ANY pointers tragedy

Jsmit

Member
Join Date
Aug 2006
Location
Alblasserdam
Posts
18
Hello someone,

I'm in a struggle with my Siemens S7 environment when I create an FB with an formal parameter (INPUT or IN_OUT) of type ANY and try to copy/pass on this parameter to a function that is called from within the FB. Can anyone please help out?

Ps. A function that copy's the ANY pointer from the INPUT to a TEMP is also fine. The called functions actually do accept a TEMP ANY pointer.

Riddle me this, Riddle me that....

Thanx for your troubles in advance.

Joël
 
Simplest way:
FUNCTION_BLOCK FB 1
TITLE =
VERSION : 0.1

VAR_INPUT
FB_In1 : ANY ;
END_VAR
VAR_TEMP
FC_Any : ANY ;
RetVal : INT ;
END_VAR
BEGIN
NETWORK
TITLE =

CALL "BLKMOV" (
SRCBLK := P#DIX 0.0 BYTE 10,
RET_VAL := #RetVal,
DSTBLK := P#L 0.0 BYTE 10);


NETWORK
TITLE =

CALL FC 1 (
In1 := #FC_Any);



END_FUNCTION_BLOCK

But take into accordance: if you insert something before FB_In1 or #Fc_Any you function will crash.
 
FUNCTION_BLOCK FB 1
TITLE =
VERSION : 0.1


VAR_INPUT
FB_In1 : ANY ;
END_VAR
VAR_TEMP
FC_Any : ANY ;
RetVal : INT ;
SaveAR2 : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =

TAR2 ;
T #SaveAR2;
NETWORK
TITLE =

LAR1 P##FC_Any;
LAR2 P##FB_In1;
NETWORK
TITLE =

L D [AR2,P#0.0];
T D [AR1,P#0.0];
L D [AR2,P#4.0];
T D [AR1,P#4.0];
L W [AR2,P#8.0];
T W [AR1,P#8.0];
NETWORK
TITLE =

L #SaveAR2;
LAR2 ;
NETWORK
TITLE =

CALL FC 1 (
In1 := #FC_Any);



END_FUNCTION_BLOCK

This is another way. It's much more safe because pointers aren't defined as absolute addresses. But nothing else must be inserted when you work with AR (only TEMP allowed)! Try to download it and watch AR2 content.
 
Jsmit said:
I'm in a struggle with my Siemens S7 environment when I create an FB with an formal parameter (INPUT or IN_OUT) of type ANY and try to copy/pass on this parameter to a function that is called from within the FB. Can anyone please help out?

Ps. A function that copy's the ANY pointer from the INPUT to a TEMP is also fine. The called functions actually do accept a TEMP ANY pointer.

Riddle me this, Riddle me that....

Joël

That's just the way it is.
 
Thanx guys for hellping me out so quickly, I'll try your suggestions later this day. I'll report back when I have it working.
 
The second one is the way to go.

Be careful though if you are moving data from into the TEMP area.

I have done this at times using SFC20 (MOVE), for the temp area you have to change the memory area pointer (BYTE 6) from B#16#86 (LOCAL) to B#16#87 (PREVIOUS LOCAL) before calling SCF20, because once you are in SFC20, the TEMP area you are writing to is obviously in the previous block, the calling block.
 
PeterW said:
The second one is the way to go.

Be careful though if you are moving data from into the TEMP area.

I have done this at times using SFC20 (MOVE), for the temp area you have to change the memory area pointer (BYTE 6) from B#16#86 (LOCAL) to B#16#87 (PREVIOUS LOCAL) before calling SCF20, because once you are in SFC20, the TEMP area you are writing to is obviously in the previous block, the calling block.
Exactly, Peter. Haste is bad assistant...
 
As already pointed out, you can get into a world of pain when dealing with indirect addressing and function blocks that need to pass on any pointers, particularly if multiple instance function blocks are used.

To overcome the problem of referencing local memory directly (and hence getting in a mess if you edit the local data area and forget to update your accesses), I use a named structure in the temp area which is arranged in the same format as an any pointer. You can now reference this named area and the code will still work if you change it's location by adding more temp variables. Below is an example, FB2 has two instances of FB316 passing on an any pointer to FC316 and FC317. (FC316 and FC317 contain the same code - they are duplicated just to allow you to monitor things more easily!).
If you copy/paste the following code into a source folder file and compile it, the blocks will appear in the blocks folder.
All you need to do is insert a call to FB2 (I used instance DB2) in OB1. This code has been tested in the simulator.

Code:
FUNCTION FC 316 : VOID
TITLE =
//
//
VERSION : 0.1
 
VAR_INPUT
pAny : ANY ; 
END_VAR
VAR_TEMP
AnyPointer : STRUCT 
wType : WORD ; 
iQuantity : INT ; 
iDBNumber : INT ; 
dwAreaPointer : DWORD ; 
END_STRUCT ; 
dwSavedAr2 : DWORD ; 
END_VAR
BEGIN
NETWORK
TITLE =passing on an any pointer (FC)
	 L	 P##pAny; //get address of parameter in V area
	 LAR1 ; //point to it with AR1
	 L	 D [AR1,P#6.0]; //get the area pointer for the original any pointer
	 LAR1 ; //point to this with AR1
	 L	 W [AR1,P#0.0]; //get pointer data
	 T	 #AnyPointer.wType; 
	 L	 W [AR1,P#2.0]; 
	 T	 #AnyPointer.iQuantity; 
	 L	 W [AR1,P#4.0]; 
	 T	 #AnyPointer.iDBNumber; 
	 L	 D [AR1,P#6.0]; 
	 T	 #AnyPointer.dwAreaPointer; 
END_FUNCTION
FUNCTION FC 317 : VOID
TITLE =
//
//
VERSION : 0.1
 
VAR_INPUT
pAny : ANY ; 
END_VAR
VAR_TEMP
AnyPointer : STRUCT 
wType : WORD ; 
iQuantity : INT ; 
iDBNumber : INT ; 
dwAreaPointer : DWORD ; 
END_STRUCT ; 
dwSavedAr2 : DWORD ; 
END_VAR
BEGIN
NETWORK
TITLE =passing on an any pointer (FC)
	 L	 P##pAny; //get address of parameter in V area
	 LAR1 ; //point to it with AR1
	 L	 D [AR1,P#6.0]; //get the area pointer for the original any pointer
	 LAR1 ; //point to this with AR1
	 L	 W [AR1,P#0.0]; //get pointer data
	 T	 #AnyPointer.wType; 
	 L	 W [AR1,P#2.0]; 
	 T	 #AnyPointer.iQuantity; 
	 L	 W [AR1,P#4.0]; 
	 T	 #AnyPointer.iDBNumber; 
	 L	 D [AR1,P#6.0]; 
	 T	 #AnyPointer.dwAreaPointer; 
END_FUNCTION
FUNCTION_BLOCK FB 316
TITLE =
VERSION : 0.1
 
VAR_INPUT
pAny : ANY ; 
END_VAR
VAR_TEMP
AnyPointer : STRUCT 
wType : WORD ; 
iQuantity : INT ; 
iDBNumber : INT ; 
dwAreaPointer : DWORD ; 
END_STRUCT ; 
dwSavedAr2 : DWORD ; 
bCallFC316 : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =passing on an any pointer (FB)
	 TAR2 #dwSavedAr2; //save current value of AR2
	 L	 P##pAny; //pointer to parameter in instance
	 AD	DW#16#7FFFF; //mask off area
	 TAR2 ; //get current instance
	 +D	; //add parameter offset
	 LAR2 ; //for indirect address
	 CDB ; //global DB instance DB swap
//****
//no stat or parameter access allowed
//****
	 L	 W [AR2,P#0.0]; 
	 T	 #AnyPointer.wType; 
	 L	 W [AR2,P#2.0]; 
	 T	 #AnyPointer.iQuantity; 
	 L	 W [AR2,P#4.0]; 
	 T	 #AnyPointer.iDBNumber; 
	 L	 D [AR2,P#6.0]; 
	 T	 #AnyPointer.dwAreaPointer; 
	 CDB ; //DB's back to how they were
	 LAR2 #dwSavedAr2; //ar2 back to how it was
//****
//stat and parameter access now allowed
//****
NETWORK
TITLE =check function to call 
	 L	 #AnyPointer.dwAreaPointer; 
	 AW	W#16#FFFF; 
	 L	 316; 
	 ==I ; 
	 =	 #bCallFC316; 
NETWORK
TITLE =
	 AN	#bCallFC316; 
	 JNB _001; 
	 CALL FC 317 (
		 pAny					 := #AnyPointer);
_001: NOP 0; 
NETWORK
TITLE =
	 A	 #bCallFC316; 
	 JNB _002; 
	 CALL FC 316 (
		 pAny					 := #AnyPointer);
_002: NOP 0; 
NETWORK
TITLE =
 
END_FUNCTION_BLOCK
 
FUNCTION_BLOCK FB 2
TITLE =
VERSION : 0.1
 
VAR
fbAny1 : FB 316; 
fbAny2 : FB 316; 
END_VAR
BEGIN
NETWORK
TITLE =
	 CALL #fbAny1 (
		 pAny					 := FC 316);
	 NOP 0; 
NETWORK
TITLE =
	 CALL #fbAny2 (
		 pAny					 := DB2.DBX	0.0);
	 NOP 0; 
END_FUNCTION_BLOCK

Stand back and light the blue touch paper !
 
Last edited:
Simon, thank you. Your examlpe is very interesting. Most interesting is this part from FC316 and FC317:
L D [AR1,P#6.0]; //get the area pointer for the original any pointer
LAR1 ; //point to this with AR1
Can you explain it for me and for others? Parameter pAny is passed to FC through FB316 L area (V area in FC). It's was clear for me. But V20.0... doesn't contains original pointer - it poins to AnyPointer of FB316. ANY type IN parameter is passed to FB as is, but to FC this parameter is passed indirectly. Is it true?
Maybe you can explain difference in IN parameter passing to FB and FC?
 
The way parameters are passed depends on the parameter type and if it's an FC or FB.

FC or FB calling FC - In the calling FC/FB if the parameter is an any pointer (DB60.DBW0.0 BYTE 8 for example), then the V area in the called FC will contain the any pointer data (indirect). If the parameter in the calling FC/FB is an ANY (e.g. an ANY type declared in the temp area), the the V area in the called FC contains an any pointer to an any pointer (double indirect).

The transferring of parameters in the case of functions and function blocks is described in Bergers book.
 

Similar Topics

Hello, I've just came out of a call where a program that was modified two weeks ago threw the processor into fault. The program has been done...
Replies
9
Views
3,464
I'm trying to get a 5069-L306er to talk to a Automation Direct ProSence Controller by using RA's AOI for modbus client but its stuck not getting a...
Replies
9
Views
1,878
The last time I did anything with Wonderware was just after the dot com bust. Boy, I feel old. Anyway, it looks like I will get the chance to...
Replies
3
Views
1,512
Hi guys, Some pointers needed: Having PC with WIN7 pro X64 and Amsamotion clone of 6ES7 972-0CB20-0XA0 cable and need to backup VIPA cpu...
Replies
14
Views
3,112
Is there any form of Reference Type or Pointer Type like Codesys has? I am aware that you can nut a tag in the index of an array reference. but...
Replies
7
Views
1,886
Back
Top Bottom