Hi Folks,
I'm having problems completing a FB and suspect my pointer programming maybe the issue.
The purpose of the FB is to transfer a variable amount of configurations 171 bytes long to a CP module and then read back the status.
The start address of each config offset is every 218 bytes.
When manually entering the offset prior to the SFC call - it works as i would expect
Since trying to add the offset indirectly - it fails miserably!!
i'm using 64bit windows 7 and i cannot get breakpoints/debug to work which would be extremely useful in this situation.
so here i am before the remainder of my hair is gone....
i have constructed the ANY pointer as follows;
pAny is a Temp of type ANY
iData is a IN variable of type INT = 171 (bytes)
dbDatabase is a IN variable of type BLOCK_DB
iOffset is STATIC variable of type INT
i have a Loopindex INT which adds 218 bytes each unsuccessful pass so
when loopindex = 0 DBx.dbx0.0 Byte 171
When loopindex = 1 DBx.dbx218.0 Byte 171
When loopindex = 2 DBx.dbx436.0 Byte 171
etc
until maximum reached.
does this look ok?
I did originally try to write the code inside a loop but didn't think it would work well with the SFC calls, so my second implementation used a Jump list.
Here is the complete code in case it will help ;
The code does loop through and offsets are added each pass - however the DB transfer only works on the first pass.
Thanks in advance for any assistance offered
I'm having problems completing a FB and suspect my pointer programming maybe the issue.
The purpose of the FB is to transfer a variable amount of configurations 171 bytes long to a CP module and then read back the status.
The start address of each config offset is every 218 bytes.
When manually entering the offset prior to the SFC call - it works as i would expect
Since trying to add the offset indirectly - it fails miserably!!
i'm using 64bit windows 7 and i cannot get breakpoints/debug to work which would be extremely useful in this situation.
so here i am before the remainder of my hair is gone....
i have constructed the ANY pointer as follows;
LAR1 P##pAny;
L W#16#1002; // Byte 0 = 10h for S7, Byte 1 = 02 (DataType Byte)
T W [AR1,P#0.0];
L #iData; // Byte 2&3 RepetitionFactor (171 Bytes)
T W [AR1,P#2.0];
OPN #DbDataBase;
L DBNO; // Byte 4 & 5 Db Number OR 0 (non Db Data)
T W [AR1,P#4.0];
L DW#16#84000000; // Byte 6 MEMORY AREA = 84 (DB) & 7,8,9 BYTE/BIT ADDRESS AREA
L #iOffset; // address of data start
SLD 3;
+D ;
T D [AR1,P#6.0];
pAny is a Temp of type ANY
iData is a IN variable of type INT = 171 (bytes)
dbDatabase is a IN variable of type BLOCK_DB
iOffset is STATIC variable of type INT
i have a Loopindex INT which adds 218 bytes each unsuccessful pass so
when loopindex = 0 DBx.dbx0.0 Byte 171
When loopindex = 1 DBx.dbx218.0 Byte 171
When loopindex = 2 DBx.dbx436.0 Byte 171
etc
until maximum reached.
does this look ok?
I did originally try to write the code inside a loop but didn't think it would work well with the SFC calls, so my second implementation used a Jump list.
Here is the complete code in case it will help ;
FUNCTION_BLOCK "Fb1Test"
TITLE =
VERSION : 0.1
VAR_INPUT
wModuleAddress : WORD ;
iNrOfJigs : INT ; //Number of Configured Jigs
DbDataBase : BLOCK_DB ; //Address of Data Start
iData : INT ; //Length of Data in Bytes
iBoundary : INT ; //Address Boundary
END_VAR
VAR_OUTPUT
Result0 : BOOL ;
Result1 : BOOL ;
Result2 : BOOL ;
END_VAR
VAR
iStepCounter : INT ;
Off : BOOL ;
iLoopIndex : INT ;
iOffset : INT ;
DSO : STRUCT
DS0_0 : BYTE ;
DS0_1 : BYTE ;
DS0_2 : BYTE ;
DS0_3 : BYTE ;
FV4 : BYTE ; //Fixed @ 60H
FV5 : BYTE ; //Fixed @ 00H
FV6 : BYTE ; //Fixed @ 40H
SlaveError00_07A : BYTE ;
SlaveError08_15A : BYTE ;
SlaveError16_23A : BYTE ;
SlaveError24_31A : BYTE ;
SlaveError00B_7B : BYTE ;
SlaveError08_15B : BYTE ;
SlaveError16_23B : BYTE ;
SlaveError24_31B : BYTE ;
Reserved : BYTE ;
Reserved1 : BYTE ;
Reserved2 : BYTE ;
END_STRUCT ;
CheckBit : BOOL ;
RetValSFC58 : INT ;
Sfc58Busy : BOOL ;
RetValSFC51 : INT ;
Sfc51Busy : BOOL ;
AslavesOk : BOOL ;
bSlavesOk : BOOL ;
ConfigOk : BOOL ;
END_VAR
VAR_TEMP
DbJig : INT ;
SaveAr1 : DWORD ;
SaveAr2 : DWORD ;
pAny : ANY ;
Dummy : BYTE ;
SzlHeader : STRUCT
Len : WORD ;
nr : WORD ;
END_STRUCT ;
command : BYTE ;
ok : BOOL ;
Result : INT ;
bTrue : BOOL ;
END_VAR
BEGIN
NETWORK
TITLE =
//
//
//
//
//
L #iStepCounter;
JL i;
JU Idle; // 0 Ready to Start
JU Prep; // 1 Indirect Addressing for Write Command
JU Send; // 2 Write Config to CP
JU Read; // 3 Read Status of CP
JU DSO; // 4 Check Dso
JU Next; // 5 Prepare next Data Set
JU Done; // 6 Test Complete - View Results
i: JU BE; // 7 Block End
NETWORK
TITLE =
Idle: L 0;
T #iOffset;
T #iLoopIndex;
AN M 4.0; // Run comparison
JC BE;
L 1;
T #iStepCounter;
NETWORK
TITLE =Step 1: Prepare Data
//
//
Prep: NOP 0;
// Any Pointer code moved to Step 2
L 2;
T #iStepCounter;
NETWORK
TITLE =Step 2: Send Data
//// Loop 0 slaves 1,2 RD.jig (Offset 0)
//// Loop 1 slaves 1, FD.jig (Offset 218)
//// Loop 2 3 slaves 1,2,16 Test (Offset 436)
Send: NOP 0;
// Make sure b#16#3A is defined in Byte 0 of Each Jig Entry!!! OB100
// NOTE!!!
// offset is 218 bytes between configs
// Send length is only 171 bytes in total!
LAR1 P##pAny;
L W#16#1002; // Byte 0 = 10h for S7, Byte 1 = 02 (DataType Byte)
T W [AR1,P#0.0];
L #iData; // Byte 2&3 RepetitionFactor (171 Bytes)
T W [AR1,P#2.0];
OPN #DbDataBase;
L DBNO; // Byte 4 & 5 Db Number OR 0 (non Db Data)
T W [AR1,P#4.0];
L DW#16#84000000; // Byte 6 MEMORY AREA = 84 (DB) & 7,8,9 BYTE/BIT ADDRESS AREA
L #iOffset; // address of data start
SLD 3;
+D ;
T D [AR1,P#6.0];
CALL "WR_REC" (
REQ := TRUE,
IOID := B#16#54,// IOID = 54H (Input or mixed module)
LADDR := #wModuleAddress,
RECNUM := B#16#2,
RECORD := #pAny,
RET_VAL := #RetValSFC58,
BUSY := #Sfc58Busy);
L #RetValSFC58;
L W#16#80C2;
==I ;
AN #Sfc58Busy;
JCN m001;
L 3;
T #iStepCounter;
m001: JU BE; // stay on Step 2
NETWORK
TITLE =Step 3: Read in Diagnostic Data
Read: NOP 0;
// Query the DSO/DDR (Diagnostic Data Record DS1)
CALL "RDSYSST" (
REQ := TRUE,
SZL_ID := W#16#B3,// Ds1 via Logical Address
INDEX := #wModuleAddress,
RET_VAL := #RetValSFC51,
BUSY := #Sfc51Busy,
SZL_HEADER := #SzlHeader,
DR := #DSO);
L #RetValSFC51;
L W#16#0;
==I ;
AN #Sfc51Busy;
JCN m003;
L 4;
JU m004;
m003: L 3;
m004: T #iStepCounter;
JU BE;
NETWORK
TITLE =Step 4: Review DSO results
DSO: A( ;
L #DSO.SlaveError00_07A;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError08_15A;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError16_23A;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError24_31A;
L B#16#0;
==I ;
) ;
= #AslavesOk;
//--------------------------------------
A( ;
L #DSO.SlaveError00B_7B;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError08_15B;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError16_23B;
L B#16#0;
==I ;
) ;
A( ;
L #DSO.SlaveError24_31B;
L B#16#0;
==I ;
) ;
= #bSlavesOk;
//--------------------------------------
A #AslavesOk;
A #bSlavesOk;
S #ConfigOk;
AN #ConfigOk;
JC Nok;
L 6;
JU Ok;
Nok: L 5;
Ok: T #iStepCounter;
JU BE;
NETWORK
TITLE =New Step 5
Next: L #iLoopIndex;
L #iNrOfJigs;
<I ;
JCN m501;
L #iLoopIndex;
INC 1;
T #iLoopIndex;
L #iOffset;
L #iBoundary;
+I ;
T #iOffset;
m501: L #iBoundary;
L #iNrOfJigs;
*I ;
T #Result;
L #iOffset;
L #Result;
<I ;
JCN m502;
L 1;
T #iStepCounter;
JU BE;
m502: A( ;
O( ;
L #iLoopIndex;
L #iNrOfJigs;
>=I ;
) ;
O( ;
L #iOffset;
L #Result;
>=I ;
) ;
) ;
JNB m503;
L 6;
T #iStepCounter;
m503: JU BE;
NETWORK
TITLE =Step 6:
Done: SET ;
R M 4.0;
R #Result0;
R #Result1;
R #Result2;
// match @ First Pass?
A #ConfigOk;
A( ;
L #iLoopIndex;
L 0;
==I ;
) ;
S #Result0;
// match @ Second Pass?
A #ConfigOk;
A( ;
L #iLoopIndex;
L 1;
==I ;
) ;
S #Result1;
// match @ Third Pass?
A #ConfigOk;
A( ;
L #iLoopIndex;
L 2;
==I ;
) ;
S #Result2;
// for Debug
L #iOffset;
T MW 100;
L #iLoopIndex;
T MW 102;
// Reset Ready for next cycle
L 0;
T #iStepCounter;
T #iOffset;
T #iLoopIndex;
NETWORK
TITLE =Step 7: End of Function Block
BE: BE ;
END_FUNCTION_BLOCK
The code does loop through and offsets are added each pass - however the DB transfer only works on the first pass.
Thanks in advance for any assistance offered
Last edited: