Skip to content

Commit

Permalink
Merge pull request #85 from StefanHasensperling/master
Browse files Browse the repository at this point in the history
Bug fixes in Block Interface Parsing
  • Loading branch information
jogibear9988 authored Sep 21, 2017
2 parents c5342de + f95bd36 commit 0e4accc
Show file tree
Hide file tree
Showing 11 changed files with 883 additions and 13 deletions.
15 changes: 14 additions & 1 deletion LibNoDaveConnectionLibrary/DataTypes/Blocks/DataBlockRow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ public virtual string DataTypeAsString
get
{
string retVal = "";

//For arrays add the Declared dimension
if (IsArray)
{
retVal += "ARRAY [";
Expand All @@ -159,10 +161,21 @@ public virtual string DataTypeAsString
}
retVal += "] OF ";
}
retVal += DataType.ToString();

//if the row is an MultiInstance Static FB or SFB, then mention only the Block Number
//in this case omit the Datatype entirely and just write the referenced Block number
if (DataType == S7DataRowType.MultiInst_FB)
retVal += "FB" + DataTypeBlockNumber.ToString();
else if (DataType == S7DataRowType.MultiInst_SFB)
retVal += "SFB" + DataTypeBlockNumber.ToString();
else
retVal += DataType.ToString();

//in case of Block types, add the actual Block number as well
if (DataType == S7DataRowType.FB || DataType == S7DataRowType.UDT || DataType == S7DataRowType.SFB)
retVal += DataTypeBlockNumber.ToString();

//for strings mention the String Declaration size
if (DataType == S7DataRowType.STRING)
retVal += "[" + StringSize.ToString() + "]";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,26 @@ public enum S7DataRowType
STRING = 0x13,

POINTER = 0x14,

/// <summary>
/// an declaration for an FB as Multi instance parameter. May only occur in STATIC Block declaration
/// </summary>
MultiInst_FB = 0x15,

ANY = 0x16,

//The values below here are Only Legal for Parameters...

BLOCK_FB = 0x17,
BLOCK_FC = 0x18,
BLOCK_DB = 0x19,
BLOCK_SDB = 0x1a,
BLOCK_FB = 0x17, //Only valid as IN
BLOCK_FC = 0x18, //Only valid as IN
BLOCK_DB = 0x19, //Only valid as IN
BLOCK_SDB = 0x1a, //Only valid as IN

/// <summary>
/// an declaration for an System-FB as Multi instance parameter. May only occur in STATIC Block declaration
/// </summary>
MultiInst_SFB = 0x1b,

COUNTER = 0x1c,
TIMER = 0x1d,
UNKNOWN = 0xff,
Expand Down
14 changes: 13 additions & 1 deletion LibNoDaveConnectionLibrary/Documentation/MC7 Block Format.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,19 @@ Interface
IntfStrt + IntfHeader + x + 9-10 Upper Bound of 2nd Dimensino if any
...

4. Strings: Fixed length 3 bytes
4. MultiInstance BLOCK Paraemters: fixed length 3 bytes
------------------------------------
This descriptor intem is only used for MultiInstance FB or SFB references Parameters. It is only valid for STATIC areas
Be aware that these items are usually followed by an structure corresponging to the Interface of the Referenced BLOCK.

IntfStrt + IntfHeader + x + 0 Data Type: see S7DataRowType enumeration
IntfStrt + IntfHeader + x + 1 Block Number LSB
IntfStrt + IntfHeader + x + 2 Block Number MSB

These are often seen when introducing Multi instances of SFB's, such as SFB14 "GET". In this case the
datatype is BLOCK_SFB, the Block LSB is 14 and MSB is 0

5. Strings: Fixed length 3 bytes
------------------------------------
This descriptor intem is only used for strings, and kind of the same as an Structure
IntfStrt + IntfHeader + x + 0 Data Type: see S7DataRowType enumeration: Structures always have 0x11
Expand Down
46 changes: 39 additions & 7 deletions LibNoDaveConnectionLibrary/PLCs/S7_xxx/MC7/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -694,12 +694,26 @@ internal static S7DataRow GetInterface(byte[] interfaceBytes, byte[] startValueB
GetVarTypeEN(parameterRETVAL, DataType, false, false, VarNameGen.GetNextVarName(), interfaceBytes,ref InterfacePos, startValueBytes, ref StartValuePos, ref ParaList, ref StackNr, VarNameGen, myBlk);
}
break;

default:

//There is an special case for Multi Instance Block paraemters
//These can only ever occur in STATIC areas of Funciton Blocks
switch (DataType)
{
throw new Exception(string.Format ("invalid or unknown interface declarations found while parsing the block interface at pos {0} with Paratype {1} and Datatype {2}",InterfacePos, interfaceBytes[InterfacePos +1], interfaceBytes[InterfacePos]));
case S7DataRowType.MultiInst_FB:
case S7DataRowType.MultiInst_SFB:
VarNameGenerator VarNameGen = VarNameStat;
GetVarTypeEN(parameterSTAT, DataType, false, false, VarNameGen.GetNextVarName(), interfaceBytes, ref InterfacePos, startValueBytes, ref StartValuePos, ref ParaList, ref StackNr, VarNameGen, myBlk);
break;

//if it is also not one of the Block parameters, then Abort because the value is unknown
default:
throw new Exception(string.Format("invalid or unknown interface declarations found while parsing the block interface at pos {0} with Paratype {1} and Datatype {2}", InterfacePos, interfaceBytes[InterfacePos + 1], interfaceBytes[InterfacePos]));
}
break;
}
}
}

if (actualValueBytes != null) FillActualValuesInDataBlock(parameterRoot, actualValueBytes);

Expand Down Expand Up @@ -741,12 +755,12 @@ internal static void GetVarTypeEN(S7DataRow currPar, S7DataRowType datatype, bo
case S7DataRowType.DATE_AND_TIME:
case S7DataRowType.POINTER:
case S7DataRowType.ANY:
case S7DataRowType.COUNTER:
case S7DataRowType.TIMER:
case S7DataRowType.BLOCK_FB:
case S7DataRowType.BLOCK_FC:
case S7DataRowType.BLOCK_DB:
case S7DataRowType.BLOCK_SDB:
case S7DataRowType.COUNTER:
case S7DataRowType.TIMER:
//Parese Elementary unarray datatypes from the interface
//All above datatypes have the same format:
//the Length of the Interface itema is always 2 bytes
Expand All @@ -765,6 +779,26 @@ internal static void GetVarTypeEN(S7DataRow currPar, S7DataRowType datatype, bo
InterfacePos += 2; //Interface element is always 2 bytes
break;

case S7DataRowType.MultiInst_FB:
case S7DataRowType.MultiInst_SFB:
//Parese Block datatypes from the interface
//All above datatypes have the same format:
//the Length of the Interface itema is always 3 bytes
//
//InterfacePos + 0 = Datatype: one of the BLOCK_xx types
//InterfacePos + 1 = Block number LSB
//InterfacePos + 1 = Block number MSB

Par = new S7DataRow(VarName, datatype, myBlk);

//if the type has an Start value, then parse it from the Start values
int BlockNumber = BitConverter.ToInt16(interfaceBytes, InterfacePos +1);
Par.DataTypeBlockNumber = BlockNumber;

currPar.Add(Par);
InterfacePos += 3; //Interface element is always 3 bytes
break;

case S7DataRowType.STRING:
//Parse String definition from Interface
//Strings are a special case and have neither the format of Elementary nor the collection types or Array types
Expand Down Expand Up @@ -863,9 +897,7 @@ internal static void GetVarTypeEN(S7DataRow currPar, S7DataRowType datatype, bo
break;

default:
{
throw new Exception(string.Format("invalid or unknown interface declarations found while parsing the block interface at pos {0} with Paratype {1} and Datatype {2}", InterfacePos, interfaceBytes[InterfacePos + 1], interfaceBytes[InterfacePos]));
}
throw new Exception(string.Format("invalid or unknown interface declarations found while parsing the block interface at pos {0} with Paratype {1} and Datatype {2}", InterfacePos, interfaceBytes[InterfacePos + 1], interfaceBytes[InterfacePos]));
}

ParaList.Add(VarName);
Expand Down
116 changes: 116 additions & 0 deletions ToolBoxLibUnitTests/S7Blocks/Parameter/FB3004.awl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
FB3004 :

Parameter
000.0: ROOTNODE: STRUCT
000.0: IN: STRUCT
000.0: IN0: BLOCK_DB
002.0: IN1: BLOCK_FB
004.0: IN2: BLOCK_FC
006.0: IN3: BLOCK_SDB
008.0: OUT: STRUCT
008.0: IN_OUT: STRUCT
008.0: STATIC: STRUCT
008.0: STAT0: FB3003
008.0: STAT1: STRUCT
008.0: STAT2: S5TIME := 01:02:00
010.0: STAT3: DATE := 2/3/2001 12:00:00 AM
012.0: STAT4: TIME := 1.00:02:03.0040000
016.0: STAT5: TIME_OF_DAY := 1/1/0001 1:02:03 AM
020.0: STAT6: DATE_AND_TIME := 2/3/1999 1:02:03 AM
028.0: STAT7: STRING[254] := ''1aaffdd''
284.0: STAT8: ARRAY [1..10] OF STRUCT
284.0: STAT9: S5TIME := 01:02:00
286.0: STAT10: DATE := 2/3/2001 12:00:00 AM
288.0: STAT11: TIME := 1.00:02:03.0040000
292.0: STAT12: TIME_OF_DAY := 1/1/0001 1:02:03 AM
296.0: STAT13: DATE_AND_TIME := 2/3/1999 1:02:03 AM
304.0: STAT14: STRING[254] := ''1aaffdd''
3044.0: STAT15: ARRAY [33..38] OF STRUCT
3044.0: STAT16: S5TIME := 01:02:00
3046.0: STAT17: DATE := 2/3/2001 12:00:00 AM
3048.0: STAT18: TIME := 1.00:02:03.0040000
3052.0: STAT19: TIME_OF_DAY := 1/1/0001 1:02:03 AM
3056.0: STAT20: DATE_AND_TIME := 2/3/1999 1:02:03 AM
3064.0: STAT21: STRING[254] := ''1aaffdd''
4700.0: STAT22: S5TIME := 01:02:00
4702.0: STAT23: DATE := 2/3/2001 12:00:00 AM
4704.0: STAT24: TIME := 1.00:02:03.0040000
4708.0: STAT25: TIME_OF_DAY := 1/1/0001 1:02:03 AM
4712.0: STAT26: DATE_AND_TIME := 2/3/1999 1:02:03 AM
4720.0: STAT27: STRING[254] := ''1aaffdd''
4976.0: STAT28: ARRAY [1..10] OF STRUCT
4976.0: STAT29: S5TIME := 01:02:00
4978.0: STAT30: DATE := 2/3/2001 12:00:00 AM
4980.0: STAT31: TIME := 1.00:02:03.0040000
4984.0: STAT32: TIME_OF_DAY := 1/1/0001 1:02:03 AM
4988.0: STAT33: DATE_AND_TIME := 2/3/1999 1:02:03 AM
4996.0: STAT34: STRING[254] := ''1aaffdd''
7736.0: STAT35: ARRAY [33..38] OF STRUCT
7736.0: STAT36: S5TIME := 01:02:00
7738.0: STAT37: DATE := 2/3/2001 12:00:00 AM
7740.0: STAT38: TIME := 1.00:02:03.0040000
7744.0: STAT39: TIME_OF_DAY := 1/1/0001 1:02:03 AM
7748.0: STAT40: DATE_AND_TIME := 2/3/1999 1:02:03 AM
7756.0: STAT41: STRING[254] := ''1aaffdd''
9392.0: STAT42: S5TIME := 01:02:00
9394.0: STAT43: DATE := 2/3/2001 12:00:00 AM
9396.0: STAT44: TIME := 1.00:02:03.0040000
9400.0: STAT45: TIME_OF_DAY := 1/1/0001 1:02:03 AM
9404.0: STAT46: DATE_AND_TIME
9412.0: STAT47: STRING[254]
9668.0: STAT48: ARRAY [1..10] OF STRUCT
9668.0: STAT49: S5TIME
9670.0: STAT50: DATE
9672.0: STAT51: TIME
9676.0: STAT52: TIME_OF_DAY
9680.0: STAT53: DATE_AND_TIME
9688.0: STAT54: STRING[254]
12428.0: STAT55: ARRAY [33..38] OF STRUCT
12428.0: STAT56: S5TIME
12430.0: STAT57: DATE
12432.0: STAT58: TIME
12436.0: STAT59: TIME_OF_DAY
12440.0: STAT60: DATE_AND_TIME
12448.0: STAT61: STRING[254]
14084.0: STAT62: S5TIME := 01:02:00
14086.0: STAT63: DATE := 2/3/2001 12:00:00 AM
14088.0: STAT64: TIME := 1.00:02:03.0040000
14092.0: STAT65: TIME_OF_DAY := 1/1/0001 1:02:03 AM
14096.0: STAT66: DATE_AND_TIME := 2/3/1999 1:02:03 AM
14104.0: STAT67: STRING[254] := ''1aaffdd''
14360.0: STAT68: ARRAY [1..10] OF STRUCT
14360.0: STAT69: S5TIME := 01:02:00
14362.0: STAT70: DATE := 2/3/2001 12:00:00 AM
14364.0: STAT71: TIME := 1.00:02:03.0040000
14368.0: STAT72: TIME_OF_DAY := 1/1/0001 1:02:03 AM
14372.0: STAT73: DATE_AND_TIME := 2/3/1999 1:02:03 AM
14380.0: STAT74: STRING[254] := ''1aaffdd''
17120.0: STAT75: ARRAY [33..38] OF STRUCT
17120.0: STAT76: S5TIME := 01:02:00
17122.0: STAT77: DATE := 2/3/2001 12:00:00 AM
17124.0: STAT78: TIME := 1.00:02:03.0040000
17128.0: STAT79: TIME_OF_DAY := 1/1/0001 1:02:03 AM
17132.0: STAT80: DATE_AND_TIME := 2/3/1999 1:02:03 AM
17140.0: STAT81: STRING[254] := ''1aaffdd''
18776.0: STAT82: SFB14
18776.0: STAT83: STRUCT
18776.0: STAT84: BOOL
18778.0: STAT85: WORD
18780.0: STAT86: BOOL
18780.1: STAT87: BOOL
18782.0: STAT88: WORD
18784.0: STAT89: ANY
18794.0: STAT90: ANY
18804.0: STAT91: ANY
18814.0: STAT92: ANY
18824.0: STAT93: ANY
18834.0: STAT94: ANY
18844.0: STAT95: ANY
18854.0: STAT96: ANY
18864.0: STAT97: WORD
18866.0: TEMP: STRUCT
18866.0: RET_VAL: STRUCT


AWL-Code
Netzwerk 1 :
Binary file added ToolBoxLibUnitTests/S7Blocks/Parameter/FB3004.bin
Binary file not shown.
Loading

0 comments on commit 0e4accc

Please sign in to comment.