S7: Add offset to Any Pointer for BLKMOV

Mark Whitt

Member
Join Date
Jan 2013
Location
Columbus, OH
Posts
31
Hello Folks!

I have an application where I need to copy a string into various locations within a DB. So, I've set up a Function Block to accept an Index number (I've called this #BO), an Any Pointer to the String to be copied (I've called this PTR_STRING) and a pointer to the BASE location within the DB where the indexing will start (add 84 bytes for every Index Increment).

What's happening is that the address offset is ignored and the string always gets copied to the Base Address. Obviously, there's something wrong with my STL code, but my inexperience with it is keeping me from seeing the problem. So, any help (pointers to those inclined towards puns) would be greatly appreciated!

Here's a pseudo code version of what I've done, with the STL code taken verbatim from the function.

IN Area:
PTR_BASE = Any Pointer // Any Pointer to DB base position (Index 0, the copy to here, Index 1 copy to [here + 84 bytes], etc).
BO = Int // Index value from 0 to 3. Used to calculate offset into DB.
PTR_STRING = Any Pointer // Any Pointer to string that we want to copy.


TEMP area:
pPTR_STRING = Any Pointer // Local Any Pointer to the string that will be copied.
pPTR_BASE = Any Pointer // Local Any Pointer that will be offset by an index times 84 bytes
dwtar2 = DWord // Save for AR2 register
Address_Offset = Int // Calculated Byte Offset
Return_Val = Int // Return value for BLKMOV
DB_no = Int // Data Block number. Not sure that this is needed.



// Convert pointer to string that we want to copy to a
// local pointer that BLKMOV can use.

TAR2 #dwtar2
L P##PTR_STRING
LAR1
LAR2 P##pPTR_STRING
L W [AR1,P#0.0]
T W [AR2,P#0.0]
L W [AR1,P#2.0]
T W [AR2,P#2.0]
L W [AR1,P#4.0]
T W [AR2,P#4.0]
L D [AR1,P#6.0]
T D [AR2,P#6.0]


// Use a Ladder rung to calculate offset in 84 bytes increments.
// So, if index comes in at 1 then add 84 bytes to the pointer
// that we'll be writing to.
//
MUL_I
IN1= #BO
IN2 = 84
OUT = #Address_Offset


// Now, take the destination pointer that was passed, convert it
// to a local pointer that BLKMOV can use, and add the Offset calculated above.
//
L P##PTR_BASE
LAR1

LAR2 P##pPTR_BASE // Pointer to the Array base we're writing to.
L W [AR1,P#0.0]
T W [AR2,P#0.0]
L W [AR1,P#2.0] // count

T W [AR2,P#2.0]
L W [AR1,P#4.0] // DB number
// Do I need an OPN DB here??
T W [AR2,P#4.0]
L D [AR1,P#6.0]
T D [AR2,P#6.0] // fetch area pointer
L #Address_Offset // Get the calculated Addres offset.
SLD 3 // Convert pointer to bytes
+AR2 // Add pointer to AR2

// Using Ladder for BLKMOV
SRCBLK = #pPTR_STRING // String to be copied
RET_VAL = #Return_Val // return code
DSTBLK = #pPTRBASE // Pointer into DB where the string should go.

Of course, there is a SAVE instruction at the end, and a LAR2 #dwar2 as well.

I did NOT put an open for the DB because I'm pretty sure that the BLKMOV already handles that - and the fact that the string shows up at the base address seems to confirm that.

I'm sure this is a simple matter of not understanding how to add an offset to the Any Pointer. Many thanks in advance!
 
Adding the offset to AR2 makes no sense, you have to add the offset to the area pointer of the anypointer, viz:
(untested).


LAR2 P##pPTR_BASE // Pointer to the Array base we're writing to.
L W [AR1,P#0.0]
T W [AR2,P#0.0]
L W [AR1,P#2.0] // count

T W [AR2,P#2.0]
L W [AR1,P#4.0] // DB number
// Do I need an OPN DB here??
T W [AR2,P#4.0]

L #Address_Offset // Get the calculated Addres offset.
SLD 3 // Convert pointer to bytes
L D [AR1,P#6.0] //fetch area pointer
+D // Add offset
T D [AR2,P#6.0] // updated area pointer for block move

// Using Ladder for BLKMOV
SRCBLK = #pPTR_STRING // String to be copied
RET_VAL = #Return_Val // return code
DSTBLK = #pPTRBASE // Pointer into DB where the string should go.

Of course, there is a SAVE instruction at the end, and a LAR2 #dwar2 as well.

I did NOT put an open for the DB because I'm pretty sure that the BLKMOV already handles that - and the fact that the string shows up at the base address seems to confirm that.

I'm sure this is a simple matter of not understanding how to add an offset to the Any Pointer. Many thanks in advance!
 
Any particular reason you've used a function block as opposed to a function?

If you use the function block as a multiple instance your indirect addressing of the IN area will not work.

Also, you have modified AR2 and then attempted to access BO. Once you have modified AR2 in a function block, you cannot access any of the interface variables except the temp area. Create a temp variable TEMP_BO and copy BO to it at the start of your block - use TEMP_BO for the multiply.
 
Hello L D[AR2,P#0.0],

Once again you've saved my day (week?). I almost had it at one point myself, but put the +D in the wrong place so it didn't work. I AM learning, but very slowly!

I misspoke earlier. It was a function that I was using, not a function block. But I'm glad that you mentioned about the multiple instance causing the indirect addressing of the IN area to not work. While that's not a problem now, I'm sure that's a trap that I would have eventually fallen into.

Many thanks again!

BTW, shouldn't you be in the Pub by now? What are you doing answering questions on the forum at this hour? But I'm glad that you did! :)
 

Similar Topics

Im trying to create a level indicator for water Tank i have used the ADD function while the pump is on and level increasing everything works...
Replies
9
Views
57
We are trying to poll data coming from a PLC for remote monitoring we have the IP address of the PLC and the default port number and the path is...
Replies
25
Views
414
Hello The plant is running and there is no shutdown nowadays therefore I can add 1734- AENTR and its card while PLC is in Run? I do not wanna...
Replies
1
Views
113
PLC: Fx5u CPU As Per manual High Speed Input Module can add from Navigation window  [Parameter]  [Module Information]  Right-click  [Add New...
Replies
1
Views
69
Back
Top Bottom