diff --git a/silecs-codegen/src/xml/Mapping.py b/silecs-codegen/src/xml/Mapping.py new file mode 100644 index 0000000000000000000000000000000000000000..29a6ee4df7f8533a65be35e5c024689092d94be0 --- /dev/null +++ b/silecs-codegen/src/xml/Mapping.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +global MEM_TYPE +global DI_TYPE +global DO_TYPE +global AI_TYPE +global AO_TYPE +global mappin2String + +MEM_TYPE = 0 +DI_TYPE = 1 +DO_TYPE = 2 +AI_TYPE = 3 +AO_TYPE = 4 + +mappingType2String = { MEM_TYPE: "MEM", DI_TYPE: "DI", DO_TYPE: "DO", AI_TYPE: "AI", AO_TYPE: "AO" } + +class Mapping(object): + def __init__(self,controllerAddress, type): + self.classBaseAddress = controllerAddress # start-address of the data per area type (MEM, DI,DO, AI,AO) for the given class + self.nbBlock = 0 # number of block per area type (MEM, DI,DO, AI,AO) + self.deviceDataSize = 0 # global size of one class instance (sum of block size per area type) + self.usedData = "" # data size summary per class and per area type# + self.instanceAddress = -1 # start-address of the device data + self.isDefined = False # True if the object related base-address has been defined + self.type = type # mapping-type (MEM, DI, DO,AI,AO ) + self.blockDataSize = 0 + self.blockAddress = 0 + + if controllerAddress != -1: + self.instanceAddress = 0 + self.isDefined = True + + def clearInstanceAddressIfDefined(self): + if self.isDefined: + self.instanceAddress = 0 \ No newline at end of file diff --git a/silecs-codegen/src/xml/genparam.py b/silecs-codegen/src/xml/genparam.py index d4e2c49e48739fc6b56506105bdb8a15492dc49a..236fc5f8a190901ff4017f10eee8da033f55487b 100644 --- a/silecs-codegen/src/xml/genparam.py +++ b/silecs-codegen/src/xml/genparam.py @@ -27,6 +27,7 @@ import xmltemplate import iefiles from iecommon import * +from Mapping import * from model.Class.Register import * from model.Class.Block import * from model.Class.Class import * @@ -35,28 +36,6 @@ from model.Deploy.Controller import * import model.Deploy.Device from model.Param.Param import * -class Mapping(object): - def __init__(self,classBaseAddress): - self.classBaseAddress = classBaseAddress # start-address of the data per area type (MEM, DI,DO, AI,AO) for the given class - self.nbBlock = 0 # number of block per area type (MEM, DI,DO, AI,AO) - self.deviceDataSize = 0 # global size of one class instance (sum of block size per area type) - self.usedMem = "" # data size summary per class and per area type - - -#------------------------------------------------------------------------- -# Global definitions -#------------------------------------------------------------------------- -msize = 0 # my regMemSize in the former PERL script -blockDataSize = 0 # my $blockMemSize = 0; in the former PERL script -blockAddress = 0 # my $blockAddress = 0; in the former PERL script -plcSize = 0 -plcLast = 0 -instAddr = 0 - -blockCounter = 0 # used for NI block address generation -regCounter = 0 # used for NI register address generation - - #------------------------------------------------------------------------- # Trimming: remove new-line, tabulation and spaces of the string # Used to compute CRC32 on significant data only @@ -68,395 +47,10 @@ def trim (str): str = str.replace('\n', '') return str -#------------------------------------------------------------------------- -# Return the highest bit-alignment of the given address -def whichDataAlignment(value): - if (value % 2 != 0): return 8 - if (value % 4 != 0): return 16 - if (value % 8 != 0): return 32 - return 64 - - -#------------------------------------------------------------------------- -# DATA ALIGNMENT depends on different conditions: PLC brand, model and also -# depends on type of data structure (scalar or array) -# These methods are used to compute the correct address of each register respecting -# this conditions. -# Attention!! $addr is the relative address of the register within the block including -# this alignment while $msize is still the useful memory of the data which does not include -# memory spaces because of alignment shifts of the following variables if any. -# This remark is not true for the block mem-size which naturally includes the alignment spaces. -# - -# Adjust the register address relying on the SCHNEIDER Premium/Quantum alignment constraints -# Unity Premium/Quantum is 16bits processor and base-address is interpreted as 16bit address -# Byte elements of array (including STRING) use 8bit alignment. -def alignPremiumRegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 16 - while(whichDataAlignment(addr) < algnt): - addr+=1 - msize = dim * dim2 * strLen * size #compute memory data size - if (format in ['int8', 'char']): #8bit signed type use word alignment (16bit) - msize = msize * 2 # while string and uint8-array use 8bit alignment - return addr - -# Adjust the register address relying on the SCHNEIDER M340 alignment constraints -# Unity M340 is 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping) -# 32bits alignment except for 8/16bits (16bits alignment) -# Byte elements of array (including STRING) use 8bit alignment. -def alignM340RegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 16 - if (size > 2): - algnt = 32 - while(whichDataAlignment(addr) < algnt): - addr+=1 - msize = dim * dim2 * strLen * size #compute memory data size - if (format in ['int8', 'char']): #8bit signed type use word alignment (16bit) - msize = msize * 2 # while string and uint8-array use 8bit alignment - return addr - -# Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints -# Use 16bits processor and base-address is interpreted as 16bit address -def alignDIGIRegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 16 - while(whichDataAlignment(addr) < algnt): - addr+=1 - msize = dim * dim2 * strLen * size #compute memory data size - if (format != 'string'): - if (size == 1): #but it's a 8bit type - msize = msize * 2 #so, it's a word alignment (only string use byte alignment) - return addr - -def alignCNVRegAddress(addr, format, size, dim, dim2, strLen): - global regCounter - return regCounter - -# Adjust the register relying on the SIEMENS Simatic alignment constraints -# 8bits alignment except for array and >8bits data (16bits alignment) -# In case of string, its length has to be +2 to hold info on string -def alignSimaticRegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 8 - if ((size > 1) | (dim > 1) | (dim2 > 1) | (strLen > 1)): - algnt = 16 - while(whichDataAlignment(addr) < algnt): - addr+=1 - if strLen > 1: # register is a string, - if ((strLen % 2) != 0): strLen+=1 #adjusts the global size for byte type (word alignment) - strLen+=2 #add increment to strLen first two bytes for info on string (len, maxlen) - - msize = dim * dim2 * strLen * size #compute memory data size - return addr - -# Adjust the register address relying on the BECKHOFF Twincat BC9020 alignment constraints. -# TwinCAT BCxx PLCs are 16bits processor and base-address is interpreted as 16bit address -# 8bits alignment between elements of 8bit-data array (including strings). -# In case of string, its length has to be +1 to hold end-terminator. -def alignBCxxRegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 16 - while(whichDataAlignment(addr) < algnt): - addr+=1 - - if strLen > 1: # register is a string, - strLen += 1 #TwinCAT requires '\0' string terminator. - - msize = dim * dim2 * strLen * size #compute memory data size - return addr - -# Adjust the register address relying on the BECKHOFF Twincat CX9020 alignment constraints. -# TwinCAT CXxx PLCs are 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping) -# 32bits alignment except for 8/16bits (16bits alignment). -# 8bits alignment between elements of 8bit-data array (including strings). -# In case of string, its length has to be +1 to hold end-terminator. -def alignCXxxRegAddress(addr, format, size, dim, dim2, strLen): - global msize - - # internal string/unicode to integer cast - size = int(size) - addr = int(addr) - dim = int(dim) - dim2 = int(dim2) - strLen = int(strLen) - - algnt = 16 - if (size > 2): - algnt = 32 - while(whichDataAlignment(addr) < algnt): - addr+=1 - - if strLen > 1: # register is a string, - strLen += 1 #TwinCAT requires '\0' string terminator. - - msize = dim * dim2 * strLen * size #compute memory data size - return addr - -#block-address = block DB-Number -def computeSiemensBlockBlkAddress(regAddr, classAddr, nbDev): - #Compute block mem-size at first: each block has a dedicated DB-number which contains an array of devices - #each element of the array is a structure which must be 16bits aligned! - global blockDataSize - global plcModel - global blockAddress - - # internal string/unicode to integer cast - regAddr = int(regAddr) - classAddr = int(classAddr) - nbDev = int(nbDev) - - nextBlockAddr = regAddr - algnt = whichBaseAlignment[plcModel] #get the base struct-alignment of that PLC (16bit here) - # then adjust the next block-address by respecting this base-alignment. - while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)): - nextBlockAddr+=1 - blockDataSize = nextBlockAddr - # then compute the next block DB-number and return the current one - tmpblockAddress = blockAddress - blockAddress = blockAddress + 1 - - return tmpblockAddress + classAddr - -#block-address = offset in the device memory -def computeSiemensDeviceBlkAddress(regAddr, classAddr, nbDev): - #Compute block mem-size at first: each device has a dedicated DB-number which contains a sequence of blocks - #each block is a structure which must be 16bits aligned! - global blockDataSize - global plcModel - global blockAddress - - # internal string/unicode to integer cast - regAddr = int(regAddr) - classAddr = int(classAddr) - nbDev = int(nbDev) - - nextBlockAddr = regAddr - algnt = whichBaseAlignment[plcModel] #get the base struct-alignment of that PLC (16bit here) - #then adjust the next block-address by respecting this base-alignment. - while(int(whichDataAlignment(nextBlockAddr)) < int(algnt)): - nextBlockAddr+=1 - blockDataSize = nextBlockAddr - #then compute the next block DB-number and return the current one - tmpblockAddress = blockAddress - blockAddress = blockAddress + blockDataSize - return tmpblockAddress - - -# Block-address = absolute address in the PLC memory -def computeSchneiderBlockBlkAddress(regAddr, classAddr, nbDev): - global blockDataSize - global plcModel - global blockAddress - - # Internal string/unicode to integer cast - regAddr = int(regAddr) - classAddr = int(classAddr) - nbDev = int(nbDev) - - # Compute block mem-size at first: - # It corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER. - nextBlockAddr = regAddr - - # Each data-block for each class and device will be aligned on the worst-case alignment - # of the given PLC. This logic allows having a unique address computing whatever the mode (DEVICE/BLOCK) - # and the PLC model (16bits or 32bits). - algnt = whichBaseAlignment[plcModel] # get the "worst-case" base-alignment of that PLC - #then adjust the next block-address by respecting this base-alignment. - while(whichDataAlignment(nextBlockAddr) < int(algnt)): - nextBlockAddr+=1 - blockDataSize = nextBlockAddr - # then compute the next block DB-number and return the current one - tmpblockAddress = blockAddress - # next absolute address: relies on the global class-address - blockAddress = blockAddress + (nbDev * blockDataSize) - return classAddr + tmpblockAddress - - -# Block-address = offset in the device memory -def computeSchneiderDeviceBlkAddress(regAddr, classAddr, nbDev): - global blockDataSize - global plcModel - global blockAddress - - # internal string/unicode to integer cast - regAddr = int(regAddr) - classAddr = int(classAddr) - nbDev = int(nbDev) - - #Compute block mem-size at first: - #it corresponds to the next potential address that is 16bits or 32bits with SCHNEIDER. - nextBlockAddr = regAddr - #Each data-block for each class and device will be aligned on the worst-case alignment - #of the given PLC. This logic allows having a unique adress computing whatever the mode (DEVICE/BLOCK) - #and the PLC model (16bits or 32bits). - algnt = whichBaseAlignment[plcModel] #get the "worst-case" base-alignment of that PLC - #then adjust the next block-address by respecting this base-alignment. - while(whichDataAlignment(nextBlockAddr) < int(algnt)): - nextBlockAddr+=1 - blockDataSize = nextBlockAddr - #then compute the next block DB-number and return the current one - tmpblockAddress = blockAddress - #next relative address: independent from the global class-address - blockAddress = blockAddress + blockDataSize - return tmpblockAddress - -def computeNiDeviceBlkAddress(regAddr, classAddr, nbDev): - global blockCounter - blockCounter = blockCounter + 1 - return blockCounter - -#------------------------------------------------------------------------- -# Compute the next register address relying on the data start-address and size. -def computeAnyNextRegAddress(brand, addr, dim, dim2=1): - global msize - - # internal string/unicode to integer cast - addr = int(addr) - dim = int (dim) - dim2 = int(dim2) - - addr = addr + msize; #compute the next address for any case - if (brand == 'SIEMENS'): - # SIEMENS requires specific treatment in case of array. - if ((dim > 1) | (dim2 > 1)): - #SIEMENS array is always followed by 16bits adressing - algnt = 16 - while(whichDataAlignment(addr) < algnt): - addr+=1 - elif (brand == 'NI'): - msize = 0 - return addr - - -#------------------------------------------------------------------------- -def computeAnyBlockInstAddress(classAddr, devSize): - global instAddr - tmpInstAddr = instAddr - instAddr = instAddr + 1 #device-index - return tmpInstAddr - -def computeSiemensDeviceInstAddress(classAddr, devSize): - global instAddr - tmpInstAddr = instAddr - instAddr = instAddr + 1 #device DB-number - return tmpInstAddr + classAddr - -def computeSchneiderDeviceInstAddress(classAddr, devSize): - global instAddr - tmpInstAddr = instAddr - instAddr = instAddr + devSize #absolute address - return tmpInstAddr + classAddr - -def computeNiDeviceInstAddress(classAddr, devSize): - return 0 -#------------------------------------------------------------------------- -# Compute the base DB-number of the next class in the SIEMENS PLC memory -# BLOCK mode requires 1 DB per class block -def computeSiemensBlockNextBaseAddress(mapping, nbDev): - global plcLast - global plcSize - - # internal string/unicode to integer cast - classAddr = int(mapping.classBaseAddress) - nbBlk = int(mapping.nbBlock) - devSize = int(mapping.deviceDataSize) - nbDev = int(nbDev) - - byteSize = nbDev * devSize - plcSize = int(plcSize) + int(byteSize) #global size of the plc configuration - startDB = classAddr #first DB used for this class - plcLast = classAddr + nbBlk - 1 #last DB used - mapping.usedMem = "DB%d..DB%d / %d bytes"%(startDB,plcLast,byteSize) - return plcLast + 1 #next DB number - -# Compute the base DB-number of the next instance in the SIEMENS PLC memory -# DEVICE mode requires 1 DB per class instance -def computeSiemensDeviceNextBaseAddress(mapping, nbDev): - global plcLast - global plcSize - - # internal string/unicode to integer cast - classAddr = int(mapping.classBaseAddress) - nbBlk = int(mapping.nbBlock) - devSize = int(mapping.deviceDataSize) - nbDev = int(nbDev) - - byteSize = nbDev * devSize - plcSize = plcSize + byteSize #global size of the plc configuration - startDB = classAddr #first DB used for this class - plcLast = classAddr + nbDev - 1 #last DB used - mapping.usedMem = "DB%d..DB%d / %d bytes"%(startDB,plcLast,byteSize) - return plcLast + 1 #next DB number #next DB number - -# Compute the base-address of the next class in the SCHNEIDER PLC memory -# DEVICE or BLOCK mode use the same memory size: next base address should be the same -# 'used-mem' info is expressed in words (/2) but address is computed in bytes -def computeSchneiderAnyNextBaseAddress(mapping, nbDev): - global plcLast - global plcSize - - # internal string/unicode to integer cast - classAddr = int(mapping.classBaseAddress) - nbBlk = int(mapping.nbBlock) - devSize = int(mapping.deviceDataSize) - nbDev = int(nbDev) - - wordSize = (nbDev * devSize) / 2 - plcSize = plcSize + wordSize #global size of the plc configuration - startAddr = classAddr / 2 #first word address used for this class - plcLast = startAddr + wordSize - 1 #LAST word address used for this class - mapping.usedMem = "MW%d..MW%d / %d words"%(startAddr,plcLast,wordSize); - return (classAddr + (wordSize * 2)) #next word address expressed in bytes - -def computeNiAnyNextBaseAddress(mapping, nbDev): - return 0 - def computeChecksumController( workspacePath, deploy, controller, silecsVersion, funcGetSilecsDesignFilePath, logTopics={'errorlog': True}): majorSilecsVersion = iecommon.getMajorSilecsVersion(silecsVersion) CRC32 = zlib.crc32(trim(str(majorSilecsVersion)),0)& 0xffffffff - CRC32 = zlib.crc32(trim(str(controller.baseAddress)),CRC32)& 0xffffffff + CRC32 = zlib.crc32(trim(str(controller.address[MEM_TYPE])),CRC32)& 0xffffffff for silecsDesign in deploy.silecsDesigns: devices = controller.getDevicesOfDesign(silecsDesign.name) if len(devices) > 0: @@ -479,129 +73,10 @@ def computeChecksumClass(designDOM, CRC32, logTopics={'errorlog': True}): CRC32 = zlib.crc32(trim(str(register.dim1)),CRC32)& 0xffffffff CRC32 = zlib.crc32(trim(str(register.dim2)),CRC32)& 0xffffffff CRC32 = zlib.crc32(trim(str(register.stringLength)),CRC32)& 0xffffffff - for register in block.getDesignIORegisters(): - CRC32 = zlib.crc32(trim(register.name),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(register.format),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(str(register.dim1)),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(str(register.dim2)),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(str(register.stringLength)),CRC32)& 0xffffffff - CRC32 = zlib.crc32(trim(register.type),CRC32)& 0xffffffff return CRC32 - -# The following constant are used to align the address of a device block {set of registers}. -# With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}. -# This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model. -# Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array. -whichBaseAlignment = { - 'SIMATIC_S7-300' : '16', - 'SIMATIC_S7-400' : '16', - 'SIMATIC_S7-1200' : '16', - 'SIMATIC_S7-1500' : '16', - 'SIMATIC_ET-200S' : '16', - 'SIMATIC_S7-VIRTUAL': '16', - 'Premium' : '16', - 'Quantum' : '16', - 'M340' : '32', # any data-block of M340 model will start on 32bits address - # even if the first register of the block is a 16bit data. - 'Rabbit_RCM_4010' : '16', - 'Rabbit_RCM_2000' : '16', - 'BC9020' : '16', - 'CX9020' : '32', - 'BK9000' : '16', - 'BK9050' : '16', - 'BK9100' : '16' -} - -whichDataSize = { - 'uint8' : '1', - 'int8' : '1', - 'uint16' : '2', - 'int16' : '2', - 'uint32' : '4', - 'int32' : '4', - 'float32' : '4', - 'uint64' : '8', - 'int64' : '8', - 'float64' : '8', - 'string' : '1', - 'date' : '8', - # deprecated formats - 'char' : '1', - 'byte' : '1', - 'word' : '2', - 'dword' : '4', - 'int' : '2', - 'dint' : '4', - 'real' : '4', - 'dt' : '8' -} - -whichRegAddressFunction = { - 'SIMATIC_S7-300' : alignSimaticRegAddress, - 'SIMATIC_S7-400' : alignSimaticRegAddress, - 'SIMATIC_S7-1200' : alignSimaticRegAddress, - 'SIMATIC_S7-1500' : alignSimaticRegAddress, - 'SIMATIC_ET-200S' : alignSimaticRegAddress, - 'SIMATIC_S7-VIRTUAL' : alignSimaticRegAddress, - 'Premium' : alignPremiumRegAddress, - 'Quantum' : alignPremiumRegAddress, - 'M340' : alignM340RegAddress, - 'Compact_RIO' : alignCNVRegAddress, - 'PXI_RT' : alignCNVRegAddress, - 'PXI_Windows' : alignCNVRegAddress, - 'PC_Windows' : alignCNVRegAddress, - 'Other_Support_CNV' : alignCNVRegAddress, - 'Rabbit_RCM_4010' : alignDIGIRegAddress, - 'Rabbit_RCM_2000' : alignDIGIRegAddress, - 'BC9020' : alignBCxxRegAddress, - 'CX9020' : alignCXxxRegAddress, - 'BK9000' : alignPremiumRegAddress, - 'BK9050' : alignPremiumRegAddress, - 'BK9100' : alignPremiumRegAddress -} - -whichBlkAddressFunction = { - 'SIEMENS'+'BLOCK_MODE' : computeSiemensBlockBlkAddress, - 'SIEMENS'+'DEVICE_MODE' : computeSiemensDeviceBlkAddress, - 'SCHNEIDER'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress, - 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderDeviceBlkAddress, - 'NI'+'DEVICE_MODE' : computeNiDeviceBlkAddress, - 'DIGI'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderDeviceBlkAddress, - 'BECKHOFF'+'BLOCK_MODE' : computeSchneiderBlockBlkAddress -} - -whichInstAddressFunction = { - 'SIEMENS'+'BLOCK_MODE' : computeAnyBlockInstAddress, - 'SIEMENS'+'DEVICE_MODE' : computeSiemensDeviceInstAddress, - 'SCHNEIDER'+'BLOCK_MODE' : computeAnyBlockInstAddress, - 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderDeviceInstAddress, - 'NI'+'DEVICE_MODE' : computeNiDeviceInstAddress, - 'DIGI'+'BLOCK_MODE' : computeAnyBlockInstAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderDeviceInstAddress, - 'BECKHOFF'+'BLOCK_MODE' : computeAnyBlockInstAddress -} - -whichBaseAddressFunction = { - 'SIEMENS'+'BLOCK_MODE' : computeSiemensBlockNextBaseAddress, - 'SIEMENS'+'DEVICE_MODE' : computeSiemensDeviceNextBaseAddress, - 'SCHNEIDER'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress, - 'SCHNEIDER'+'DEVICE_MODE' : computeSchneiderAnyNextBaseAddress, - 'NI'+'DEVICE_MODE' : computeNiAnyNextBaseAddress, - 'DIGI'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress, - 'DIGI'+'DEVICE_MODE' : computeSchneiderAnyNextBaseAddress, - 'BECKHOFF'+'BLOCK_MODE' : computeSchneiderAnyNextBaseAddress -} - # Needed to encapsulate "genParam" in order to allow unit-testing (fake all file interactions) def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSilecsDeployFilePath, funcGetParameterFileDirectory, workspacePath, deployName, deployVersion, silecsVersion, logTopics={'debuglog': True}): - # Global variable links - global plcModel, plcSize, plcLast - global blockAddress, msize, blockDataSize, instAddr - global blockCounter # used for NI block address generation - global regCounter # used for NI register address generation - # Check the Deployment document exist for that PLC deployPath = funcGetSilecsDeployFilePath(workspacePath, deployName) if(not os.path.isfile(deployPath)): @@ -618,8 +93,10 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile iecommon.logDebug("create directory %s" %paramPath,logTopics) for controller in deploy.controllers: - mapping = Mapping(controller.baseAddress) - plcModel = controller.model + mappings = { MEM_TYPE: None, DI_TYPE: None, DO_TYPE: None, AI_TYPE: None, AO_TYPE: None } + for mappingType, mapping in mappings.iteritems(): + mappings[mappingType] = Mapping(controller.address[mappingType], mappingType) + # Messagges for debugging purpose iecommon.logDebug("------ XML extracted informations ------",logTopics) iecommon.logDebug("owner = " + deploy.owner,logTopics) @@ -627,7 +104,8 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile iecommon.logDebug("plcModel = " + controller.model,logTopics) iecommon.logDebug("plcBrand = " + controller.brand,logTopics) iecommon.logDebug("plcProtocol = " + controller.protocol,logTopics) - iecommon.logDebug("PLCbaseAddress = %d" %controller.baseAddress,logTopics) + for mappingType, mapping in mappings.iteritems(): + iecommon.logDebug("address" + mappingType2String[mappingType] + " = " + str(controller.address[mappingType]),logTopics) paramFile = funcGetParameterFile(workspacePath, deployName, controller.hostName ) iecommon.logInfo("Generate xml for parameters file: " + paramFile,logTopics) @@ -651,17 +129,13 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile paramClass = ParamClass() paramClass.initWithDesignClass(designClass) param.controller.addParamClass(paramClass) - - #------------------------------------------------------------------------- - # Generate section <Block></Block> - #------------------------------------------------------------------------- - blockCounter = 0 - - blockAddress = 0 # memory address of the block (using byte addressing) - mapping.nbBlock = 0 # number of block of the class + controller.blockCounter = 0 + for mappingType, mapping in mappings.iteritems(): + mapping.blockAddress = 0 + mapping.nbBlock = 0 + mapping.deviceDataSize = 0 + mapping.clearInstanceAddressIfDefined() - computeBlkAddress = whichBlkAddressFunction[controller.brand + controller.protocol] - # INNER LOOP TO ACCESS AT BLOCK LEVEL for designBlock in designClass.getDesignBlocks(): paramBlock = ParamBlock() @@ -672,18 +146,12 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile regAddress = 0 # memory address of the register (using byte addressing) blockSize = 0 # block size (sum of the register size) blockMemSize = 0 # block size (sum of the regist) - instAddr = 0 # initial class address BUG FIXED - regCounter = 0 # used for NI register address generation - alignRegAddress = whichRegAddressFunction [controller.model] - - #------------------------------------------------------------------------- - # Generate section <Register></Register> - #------------------------------------------------------------------------- + controller.regCounter = 0 # used for NI register address generation # INNER LOOP TO ACCESS AT REGISTER LEVEL for designRegister in designBlock.getDesignRegisters(): iecommon.logDebug("------ Processing Register " + designRegister.name + " ------",logTopics) # Set length attribute only for string registers - if designRegister.format == 'string': + if designRegister.format == 'string': # TODO: Port this constraint to java if controller.brand == 'DIGI': # RABBIT has 8bit memory alignment but uses 16bit word communication protocol (MODBUS). # String buffer (8bit elements) must have even number of bytes. @@ -691,59 +159,56 @@ def genParamBase( funcGetSilecsDesignFilePath, funcGetParameterFile, funcGetSile iecommon.logError("String length of %s designRegister must be an even value." %designRegister.name, False,logTopics) sys.exit(2) - # Set register size - regSize = whichDataSize[designRegister.format] - # Set register address - regAddress = alignRegAddress(regAddress, designRegister.format, regSize, designRegister.dim1, designRegister.dim2, designRegister.stringLength) - regCounter = regCounter + 1 # used for NI register address generation + regAddress = controller.alignRegAddress(designBlock, designRegister, regAddress) + controller.regCounter += 1 # used for NI register address generation # Set register mem-size paramRegister = ParamRegister() - paramRegister.initWithDesignRegister(designRegister,regSize,regAddress,msize) + paramRegister.initWithDesignRegister(designRegister,regAddress,controller.msize) # Compute address for the next register - regAddress = computeAnyNextRegAddress(controller.brand, regAddress, designRegister.dim1, designRegister.dim2) + regAddress = controller.computeNextRegAddress(designBlock, designRegister, regAddress) paramBlock.xmlNode.addChild(paramRegister.xmlNode) #paramRegister.xmlNode.shellPrintNode() #iterativelly compute the block size (accumulator initialized outside the loop) - blockSize = blockSize + (int(regSize) * designRegister.dim1 * designRegister.dim2) + blockSize = blockSize + (paramRegister.size * paramRegister.dim1 * paramRegister.dim2) # END OF INNER LOOP TO ACCESS AT REGISTER LEVEL paramBlock.setSize(blockSize) - paramBlock.setAddress(computeBlkAddress(regAddress, int(mapping.classBaseAddress),nbDevice)) - paramBlock.setMemSize(blockDataSize) - # Append block + + blockSpecificMapping = mappings[paramBlock.type] + paramBlock.setAddress(controller.computeBlkAddress(paramBlock,blockSpecificMapping, regAddress,nbDevice)) + paramBlock.setMemSize(blockSpecificMapping.blockDataSize) paramClass.xmlNode.addChild(paramBlock.xmlNode) - # Count the number of devices - mapping.nbBlock = mapping.nbBlock+1 - # Accumulate blockDataSize to compute the total mapping.deviceDataSize - mapping.deviceDataSize = mapping.deviceDataSize + blockDataSize - # END OF INNER LOOP TO ACCESS AT BLOCK LEVEL (LOOP-2) # Set block Address - paramClass.setAddress(mapping.classBaseAddress) + for mappingType, mapping in mappings.iteritems(): + paramClass.setAddress(mapping.classBaseAddress,mappingType) - computeInstAddress = whichInstAddressFunction[ controller.brand + controller.protocol ] for device in devices: instance = libxml2.newNode("Instance") instance.setProp("label", device.silecsDeviceLabel) - instance.setProp("address", str(computeInstAddress(mapping.classBaseAddress, mapping.deviceDataSize))) + instance.setProp("address", str(controller.computeInstAddress(mappings[MEM_TYPE]))) + instance.setProp("DI-address", str(controller.computeInstAddress(mappings[DI_TYPE]))) + instance.setProp("DO-address", str(controller.computeInstAddress(mappings[DO_TYPE]))) + instance.setProp("AI-address", str(controller.computeInstAddress(mappings[AI_TYPE]))) + instance.setProp("AO-address", str(controller.computeInstAddress(mappings[AO_TYPE]))) paramClass.xmlNode.addChild(instance) # Compute the memory address for the next class - computeBaseAddress = whichBaseAddressFunction [controller.brand + controller.protocol] - mapping.classBaseAddress = computeBaseAddress(mapping, nbDevice); + for mappingType, mapping in mappings.iteritems(): + controller.computeNextBaseAddress(mapping, nbDevice); - # Set class used-memory - paramClass.setUsedMemory(mapping.usedMem) - iecommon.logInfo("Used-memory for Class " + deployDesign.name + ": " + mapping.usedMem ,logTopics) + for mappingType, mapping in mappings.iteritems(): + paramClass.setUsedData(mapping.usedData,mappingType) + iecommon.logInfo("Used-"+ mappingType2String[mappingType] +" for Class " + deployDesign.name + ": " + mapping.usedData ,logTopics) #Display details about the PLC memory using for the global configuration if (controller.brand == 'SIEMENS'): # SIEMENS works with data-block addressing - plcUsedMem = "DB"+str(controller.baseAddress)+"..DB"+str(plcLast)+" / "+str(plcSize)+" bytes" + plcUsedMem = "DB"+str(controller.address[MEM_TYPE])+"..DB"+str(controller.memLast)+" / "+str(controller.memSize)+" bytes" else: # SCHNEIDER works with absolute addressing - startAddr = controller.baseAddress /2 #Memory info uses word-addressing - plcUsedMem = "MW"+str(startAddr)+"..MW"+str(plcLast)+" / "+str(plcSize)+" words" + startAddr = controller.address[MEM_TYPE] /2 #Memory info uses word-addressing + plcUsedMem = "MW"+str(startAddr)+"..MW"+str(controller.memLast)+" / "+str(controller.memSize)+" words" # print plc used memory iecommon.logInfo("Used-memory for PLC " + deploy.name + ": "+str(plcUsedMem),logTopics) diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py index ae8424d25800199d01284e19a7d7a3cdaa8f5cf2..479fb589ad127e2ff22bd4a52673905d3e2036b1 100644 --- a/silecs-codegen/src/xml/genplcsrc.py +++ b/silecs-codegen/src/xml/genplcsrc.py @@ -135,8 +135,8 @@ def generateSiemensSources(param, sourceFolderPath ,logTopics): symString = '' # for .sdf Symbol file # Prepare the Simatic Symbols (<.sdf> file) - DBnumber = param.controller.address #first data-block (SilecsHeader) starts from the base-address - UDTnumber = param.controller.address #use base data-block address for UDT number as well (to be reserved by the developer) + DBnumber = param.controller.address[MEM_TYPE] #first data-block (SilecsHeader) starts from the base-address + UDTnumber = param.controller.address[MEM_TYPE] #use base data-block address for UDT number as well (to be reserved by the developer) # Generate sources for each class that is deployed in the PLC for paramClass in param.controller.paramClasses: @@ -278,7 +278,7 @@ def generateSchneiderSources(param,sourceFolderPath,logTopics): # ---------------------------------------------------- def generateDIGISources(param,sourceFolderPath,logTopics): deviceLabel = '' - cCodeString = DIGITemplate.cHeader(param.silecsVersion, param.controller.address) + cCodeString = DIGITemplate.cHeader(param.silecsVersion, param.controller.address[MEM_TYPE]) cTypeDefinitions = '' cDataAllocation = DIGITemplate.cAllocationComment(param.controller.protocol) @@ -359,7 +359,7 @@ def generateVirtualS7Sources(param,sourceFolderPath,logTopics): protocolMode = 'BlockMode'; if param.controller.protocol == 'DEVICE_MODE': protocolMode = 'DeviceMode'; - duConstructor = virtualS7Template.vs7DuConstructor(param.deployName, param.deployVersion, protocolMode, param.controller.address) + duConstructor = virtualS7Template.vs7DuConstructor(param.deployName, param.deployVersion, protocolMode, param.controller.address[MEM_TYPE]) for paramClass in param.controller.paramClasses: blocksCodeString = '' @@ -466,9 +466,9 @@ def generateBeckhoffRegisters(param, paramClass, deviceDOM, block, deviceIndex, # Compute the register address relying on the Class Parameters file data # Attention! Beckhoff uses WORD addressing while Parameters data are expressed in bytes to be PLC independent if param.controller.model == 'BC9020': - totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address)/2 + totalAddress = (block.address - long(param.controller.address[MEM_TYPE]) + (deviceIndex * block.memSize) + register.address)/2 elif param.controller.model == 'CX9020': - totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address) + totalAddress = (block.address - long(param.controller.address[MEM_TYPE]) + (deviceIndex * block.memSize) + register.address) else: raise "PLC model not supported: " + param.controller.model diff --git a/silecs-codegen/src/xml/model/Class/Block.py b/silecs-codegen/src/xml/model/Class/Block.py index f5acb56c88d9759908fa98a058add7289e2353c6..df93b6f8d96e9fb78d8451ce48d892c7a472017f 100644 --- a/silecs-codegen/src/xml/model/Class/Block.py +++ b/silecs-codegen/src/xml/model/Class/Block.py @@ -16,16 +16,22 @@ from iecommon import * from model.Class.Register import * +from Mapping import * import libxml2 +class IOType(object): + ANALOG = "ANALOG-IO" + DIGITAL = "DIGITAL-IO" + MEMORY = "MEMORY" + class Block(object): - ___settingBlockType = "Setting-Block" - ___acquisitionBlockType = "Acquisition-Block" - ___commandBlockType = "Command-Block" - ___settingIOBlockType = "Setting-IO-Block" - ___acquisitionIOBlockType = "Acquisition-IO-Block" + ___settingBlockName = "Setting-Block" + ___acquisitionBlockName = "Acquisition-Block" + ___commandBlockName = "Command-Block" + ___settingIOBlockName = "Setting-IO-Block" + ___acquisitionIOBlockName = "Acquisition-IO-Block" def __init__(self, xmlNode): self.xmlNode = xmlNode @@ -33,36 +39,64 @@ class Block(object): self.name = xmlNode.prop("name") if xmlNode.hasProp("ioType"): self.ioType = xmlNode.prop("ioType") #only available on io-blocks - self.___type = xmlNode.get_name() + else: + self.ioType = IOType.MEMORY + self.___name = xmlNode.get_name() + self.type = None + if self.___name == self.___settingBlockName or self.___name == self.___acquisitionBlockName or self.___name == self.___commandBlockName: + self.type = MEM_TYPE + elif self.___name == self.___acquisitionIOBlockName and self.ioType == IOType.DIGITAL: + self.type = DI_TYPE + elif self.___name == self.___settingIOBlockName and self.ioType == IOType.DIGITAL: + self.type = DO_TYPE + elif self.___name == self.___acquisitionIOBlockName and self.ioType == IOType.ANALOG: + self.type = AI_TYPE + elif self.___name == self.___settingIOBlockName and self.ioType == IOType.ANALOG: + self.type = AO_TYPE + else: + raise Exception( "Cannot identify block-type of block:" + self.name ) #xmlNode.shellPrintNode() def getNameCapitalized(self): return iecommon.capitalizeString(self.name) def isReadable(self): - return self.___type == self.___settingBlockType or self.___type == self.___acquisitionBlockType + return self.___name == self.___settingBlockName or self.___name == self.___acquisitionBlockName def isWritable(self): - return self.___type == self.___settingBlockType or self.___type == self.___commandBlockType + return self.___name == self.___settingBlockName or self.___name == self.___commandBlockName def isIOBlock(self): - return self.___type == self.___settingIOBlockType or self.___type == self.___acquisitionIOBlockType + return not self.isMEMBlock() + + def isMEMBlock(self): + return self.type == MEM_TYPE + + + def isAnanlogIO(self): + return self.ioType == IOType.ANALOG + + def isDigitalIO(self): + return self.ioType == IOType.DIGITAL def isAcquisition(self): - return self.___type == self.___acquisitionBlockType + return self.___name == self.___acquisitionBlockName or self.___name == self.___acquisitionIOBlockName def isSetting(self): - return self.___type == self.___settingBlockType + return self.___name == self.___settingBlockName or self.___name == self.___settingIOBlockName def isCommand(self): - return self.___type == self.___commandBlockType + return self.___name == self.___commandBlockName - def getRegisterNodes(self): + def getMEMRegisterNodes(self): return self.xmlNode.xpathEval("*[name()='Acquisition-Register' or name()='Setting-Register' or name()='Volatile-Register']") def getIORegisterNodes(self): return self.xmlNode.xpathEval("*[name()='Acquisition-IO-Register' or name()='Setting-IO-Register']") + def getRegisterNodes(self): + return self.getMEMRegisterNodes() + self.getIORegisterNodes() + #has some additionalValues class ParamBlock(Block): def __init__(self): @@ -144,14 +178,17 @@ class DesignBlock(Block): def getFesaName(self): return self.fesaPropertyName - def getDesignRegisters(self): + def getDesignMEMRegisters(self): designRegisters = [] - for registerNode in self.getRegisterNodes(): + for registerNode in self.getMEMRegisterNodes(): designRegisters.append(DesignRegister(registerNode)) return designRegisters def getDesignIORegisters(self): designIORegisters = [] for registerNode in self.getIORegisterNodes(): - designIORegisters.append(DesignIORegister(registerNode)) - return designIORegisters \ No newline at end of file + designIORegisters.append(DesignRegister(registerNode)) + return designIORegisters + + def getDesignRegisters(self): + return self.getDesignMEMRegisters() + self.getDesignIORegisters() diff --git a/silecs-codegen/src/xml/model/Class/Class.py b/silecs-codegen/src/xml/model/Class/Class.py index 7af201c8f6e760a08cd7d6cdeb0fde32bb8df2ba..dbd12db3d3fc08ed64877e6656d8f468a0f55282 100644 --- a/silecs-codegen/src/xml/model/Class/Class.py +++ b/silecs-codegen/src/xml/model/Class/Class.py @@ -16,6 +16,7 @@ from iecommon import * from model.Class.Block import * +from Mapping import * import libxml2 class Class(object): @@ -33,31 +34,37 @@ class Class(object): return self.xmlNode.xpathEval("*[name()='Acquisition-Block' or name()='Setting-Block' or name()='Command-Block']") class ParamClass(Class): - def __init__(self): - self.address = 0 - self.usedMemory = "" + ___addressAttribute = { MEM_TYPE: "address", DI_TYPE: "DI-address", DO_TYPE: "DO-address", AI_TYPE: "AI-address", AO_TYPE: "AO-address" } + ___usedDataAttribute = { MEM_TYPE: "used-mem", DI_TYPE: "used-DI", DO_TYPE: "used-DO", AI_TYPE: "used-AI", AO_TYPE: "used-AO" } + def __init__(self): + self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) } + self.usedData = { MEM_TYPE: "", DI_TYPE: "", DO_TYPE: "", AI_TYPE: "", AO_TYPE: "" } def initWithParamClassNode(self, xmlNode): super(ParamClass, self).__init__(xmlNode) - self.address = long(self.xmlNode.prop("address")) - self.usedMemory = self.xmlNode.prop("usedMemory") + for index, address in enumerate(self.address): + self.address[index] = long(self.xmlNode.prop(self.___addressAttribute[index])) + for index, usedData in enumerate(self.usedData): + self.usedData[index] = self.xmlNode.prop(self.___usedDataAttribute[index]) def initWithDesignClass(self, designClass): newNode = libxml2.newNode(designClass.xmlNode.get_name()) newNode.newProp("name", designClass.name) newNode.newProp("version", designClass.version) super(ParamClass, self).__init__(newNode) - newNode.newProp("address", str(self.address)) - newNode.newProp("usedMemory", self.usedMemory) - - def setAddress(self,address): - self.xmlNode.setProp("address", str(address)) - self.address = address - - def setUsedMemory(self,usedMemory): - self.xmlNode.setProp("usedMemory", usedMemory) - self.usedMemory = usedMemory + for index, address in enumerate(self.address): + newNode.newProp(self.___addressAttribute[index], str(self.address[index])) + for index, usedData in enumerate(self.usedData): + newNode.newProp(self.___usedDataAttribute[index], str(self.usedData[index])) + + def setAddress(self,address,type): + self.xmlNode.setProp(self.___addressAttribute[type], str(address)) + self.address[type] = address + + def setUsedData(self,usedData,type): + self.xmlNode.setProp(self.___usedDataAttribute[type], usedData) + self.usedData[type] = usedData def getParamBlocks(self): paramBlocks = [] diff --git a/silecs-codegen/src/xml/model/Class/Register.py b/silecs-codegen/src/xml/model/Class/Register.py index e61d27097ed74b449f7deca2307087922056fcc1..2239601143a63256f2ec56d63a2ed364e61e90e2 100644 --- a/silecs-codegen/src/xml/model/Class/Register.py +++ b/silecs-codegen/src/xml/model/Class/Register.py @@ -21,6 +21,8 @@ class Register(object): ___settingRegisterType = "Setting-Register" ___acquisitionRegisterType = "Acquisition-Register" ___volatileRegisterType = "Volatile-Register" + ___settingIORegisterType = "Setting-IO-Register" + ___acquisitionIORegisterType = "Acquisition-IO-Register" def __init__(self, xmlNode): @@ -93,10 +95,10 @@ class Register(object): return self.isArray() or self.isArray2D() def isAcquisition(self): - return self.___type == self.___acquisitionRegisterType + return self.___type == self.___acquisitionRegisterType or self.___type == self.___acquisitionIORegisterType def isSetting(self): - return self.___type == self.___settingRegisterType + return self.___type == self.___settingRegisterType or self.___type == self.___settingIORegisterType def isVolatile(self): return self.___type == self.___volatileRegisterType @@ -172,6 +174,31 @@ class Register(object): typeUpperCase = silecsType[:1].upper() + silecsType[1:] # only first character if not unsigned return typeUpperCase + def getDataSize(self): + return { + 'uint8' : 1, + 'int8' : 1, + 'uint16' : 2, + 'int16' : 2, + 'uint32' : 4, + 'int32' : 4, + 'float32' : 4, + 'uint64' : 8, + 'int64' : 8, + 'float64' : 8, + 'string' : 1, + 'date' : 8, + # deprecated formats + 'char' : 1, + 'byte' : 1, + 'word' : 2, + 'dword' : 4, + 'int' : 2, + 'dint' : 4, + 'real' : 4, + 'dt' : 8 + }[self.format] + #has some additionalValues class ParamRegister(Register): @@ -187,14 +214,14 @@ class ParamRegister(Register): self.address = long(self.xmlNode.prop("address")) self.memSize = long(self.xmlNode.prop("mem-size")) - def initWithDesignRegister(self, designRegister,size,address,memSize): + def initWithDesignRegister(self, designRegister,address,memSize): newNodeTree = designRegister.xmlNode.copyNode(1) # 1 is for recursive copy if ( newNodeTree == None ): iecommon.logError('ERROR: Failed to copy register node: '+ designRegister.name +'.', True, {'errorlog': True}) super(ParamRegister, self).__init__(designRegister.xmlNode) self.xmlNode = newNodeTree - newNodeTree.newProp("size", size) - self.size = long(size) + self.size = self.getDataSize() + newNodeTree.newProp("size", str(self.size)) newNodeTree.newProp("address", str(address)) self.address = address newNodeTree.newProp("mem-size", str(memSize)) @@ -213,7 +240,7 @@ class ParamRegister(Register): self.xmlNode.setProp("mem-size", str(memSize)) self.memSize = memSize - + class DesignRegister(Register): def __init__(self, xmlNode): @@ -284,25 +311,3 @@ class DesignRegister(Register): 'dt' :'double', 'string' :'char' }[silecsDataType] - - -class DesignIORegister(DesignRegister): - def __init__(self, xmlNode): - super(DesignIORegister, self).__init__(xmlNode) - self.type = self.xmlNode.prop("type") - -class ParamIORegister(ParamRegister): - def __init__(self): - super(ParamIORegister, self).__init__() - self.type = "" - - def initWithParamIORegisterNode(self, xmlNode): - super(ParamIORegister, self).__init__() - self.type = self.xmlNode.prop("type") - self.initWithParamRegisterNode(xmlNode) - - def initWithDesignIORegister(self, designIORegister,size,address,memSize): - super(ParamIORegister, self).__init__() - self.type = self.xmlNode.prop("type") - self.initWithDesignRegister(designIORegister,size,address,memSize) - #self.xmlNode.shellPrintNode() \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Deploy/Controller.py b/silecs-codegen/src/xml/model/Deploy/Controller.py index e3df9efd36b20026d8be4d66a00d0caa1ce2b267..2dedd2a71184cdc19d8bcbc76a30fb092411b996 100644 --- a/silecs-codegen/src/xml/model/Deploy/Controller.py +++ b/silecs-codegen/src/xml/model/Deploy/Controller.py @@ -16,10 +16,24 @@ from model.Deploy.Device import * from model.Deploy.SilecsDesign import * +from model.Class.Block import * +from Mapping import * import libxml2 +#------------------------------------------------------------------------- +# Return the highest bit-alignment of the given address +def whichDataAlignment(value): + if (value % 2 != 0): return 8 + if (value % 4 != 0): return 16 + if (value % 8 != 0): return 32 + if (value % 16 != 0): return 64 + return 128 + class Controller(object): + BLOCK_MODE = "BLOCK_MODE" + DEVICE_MODE = "DEVICE_MODE" + def __init__(self, xmlNode): self.hostName = "" self.domain = "" @@ -27,12 +41,28 @@ class Controller(object): self.model = "" self.protocol = "" self.brand = "" - self.baseAddress = long(0) - self.xmlNode = None + self._baseAddress = { MEM_TYPE: None, DI_TYPE: None, DO_TYPE: None, AI_TYPE: None, AO_TYPE: None } + self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) } + self.offset = { MEM_TYPE: long(0), DI_TYPE: long(0), DO_TYPE: long(0), AI_TYPE: long(0), AO_TYPE: long(0) } + self.addressFactor = 1 + + # some variable used to calculate class/block/register-memory + self.memSize = 0 + self.memLast = 0 + self.msize = 0 + self.regCounter = 0 + self.blockCounter = 0 + + # The following constant are used to align the address of a device block {set of registers}. + # With SCHNEIDER PLC, block is aligned depending on his 'worst-case' alignement {16bits or 32bits}. + # This logic allows having a unique adress computing whatever the mode {DEVICE/BLOCK} and the PLC model. + # Concerning SIEMENS PLC, block alignment should respect the 16bits alignement constraint for Struct&Array. + self.baseAlignment = long(16) # the default + self.alligment = { IOType.MEMORY: long(16), IOType.DIGITAL: long(8), IOType.ANALOG: long(16) } # the default + self.xmlNode = xmlNode self.plcNode = None self.devices = [] - self.xmlNode = xmlNode self.hostName = xmlNode.prop("host-name") if xmlNode.hasProp("domain"): self.domain = xmlNode.prop("domain") @@ -41,6 +71,19 @@ class Controller(object): self.model = self.plcNode.prop('model') self.protocol = self.plcNode.prop('protocol') + if self.plcNode.hasProp("base-address"): + self._baseAddress[MEM_TYPE] = long(self.plcNode.prop('base-address')) + if self.plcNode.hasProp("base-DB-number"): + self._baseAddress[MEM_TYPE] = long(self.plcNode.prop('base-DB-number')) + if self.plcNode.hasProp("DI-base-address"): + self._baseAddress[DI_TYPE] = long(self.plcNode.prop("DI-base-address")) + if self.plcNode.hasProp("DO-base-address"): + self._baseAddress[DO_TYPE] = long(self.plcNode.prop("DO-base-address")) + if self.plcNode.hasProp("AI-base-address"): + self._baseAddress[AI_TYPE] = long(self.plcNode.prop("AI-base-address")) + if self.plcNode.hasProp("AO-base-address"): + self._baseAddress[AO_TYPE] = long(self.plcNode.prop("AO-base-address")) + silecsHeader = Device() silecsHeader.silecsDeviceLabel = "SilecsHeader" silecsHeader.silecsDesignRef = "SilecsHeader" @@ -51,6 +94,11 @@ class Controller(object): device.initFromXMLNode(deviceNode) self.devices.append(device) + def computeAddresses(self): + for index, baseAddress in enumerate(self._baseAddress): + if self._baseAddress[index] != None: + self.address[index] = ( self._baseAddress[index] + self.offset[index] ) * self.addressFactor + def connectDesignObjects(self,silecsDesigns): for device in self.devices: for design in silecsDesigns: @@ -96,65 +144,466 @@ class Controller(object): elif type == "NI-Controller": return NIController(controllerNode) elif type == "Virtual-Controller": - return VirtualS7Controller(controllerNode) + return SiemensController(controllerNode)#currently there is only S7-virtual else: raise Exception( "Controller-Type " + type + " not supported" ) + + def hasMappingFor(self,type): + return self._baseAddress[type] != None + def computeInstAddress(self, mapping): + if self.protocol == self.BLOCK_MODE: + return self.computeBlockInstAddress(mapping) + elif self.protocol == self.DEVICE_MODE: + return self.computeDeviceInstAddress(mapping) + else: + raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.") + + def computeBlockInstAddress(self, mapping): + raise NotImplementedError() + + def computeDeviceInstAddress(self, mapping): + raise NotImplementedError() + + def computeBlockInstAddressDefault(self, mapping): + if not mapping.isDefined: + return mapping.instanceAddress + tmpInstAddr = mapping.instanceAddress + mapping.instanceAddress += 1 #device-index + return tmpInstAddr + + def computeDeviceInstAddressDefault(self, mapping): + if not mapping.isDefined: + return mapping.instanceAddress + tmpInstAddr = mapping.instanceAddress + mapping.instanceAddress = mapping.instanceAddress + mapping.deviceDataSize #absolute address + return tmpInstAddr + mapping.classBaseAddress + + def computeNextBaseAddress(self, mapping, nbDev): + raise NotImplementedError() + + # Compute the base-address of the next class + # DEVICE or BLOCK mode use the same memory size: next base address should be the same + # 'used-mem' info is expressed in words (/2) but address is computed in bytes + def computeNextBaseAddressDefault(self, mapping, nbDev): + mapping.usedData = "0 word" + if not mapping.isDefined or ( mapping.nbBlock == 0 ) or not self.hasMappingFor(mapping.type): + return mapping.classBaseAddress + wordSize = (nbDev * mapping.deviceDataSize) / self.addressFactor + self.memSize += wordSize # global size of the plc configuration + startAddr = (mapping.classBaseAddress - self.offset[mapping.type] * self.addressFactor) / self.addressFactor # first word address used for this class + self.memLast = startAddr + wordSize - 1 # last word address used for this class + mapping.usedData = "MW%d..MW%d/%d words" % (startAddr, self.memLast, wordSize); + mapping.classBaseAddress = (mapping.classBaseAddress + (wordSize * self.addressFactor)) # next word address expressed in bytes + + def alignRegAddress(self, block, register, regAddress): + raise NotImplementedError() + + # Adjust the register address relying on the SCHNEIDER Premium/Quantum and/or Beckhoff alignment constraints + # Unity Premium/Quantum is 16bits processor and base-address is interpreted as 16bit address + # Byte elements of array (including STRING) use 8bit alignment. + def alignRegAddressDefault(self, block, register, regAddress): + algnt = 16 + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + if register.format == 'int8' or register.format == 'char':# 8bit signed type use word alignment (16bit) + self.msize = self.msize * 2 # while string and uint8-array use 8bit alignment + return regAddress + + def computeNextRegAddress(self, block, register, regAddress ): + raise NotImplementedError() + #------------------------------------------------------------------------- + # Compute the next register address relying on the data start-address and size. + def computeNextRegAddressDefault(self, block, register, regAddress ): + regAddress = regAddress + self.msize; + return regAddress + + def computeBlkAddress(self, block, mapping, regAddr, nbDev): + if self.protocol == self.BLOCK_MODE: + return self.computeBlockBlkAddress(block, mapping, regAddr, nbDev) + elif self.protocol == self.DEVICE_MODE: + return self.computeDeviceBlkAddress(block, mapping, regAddr, nbDev) + else: + raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.") + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + raise NotImplementedError() + + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + raise NotImplementedError() + + # Block-address = absolute address in the PLC memory + def computeBlockBlkAddressDefault(self, block, mapping, regAddr, nbDev): + # Compute block mem-size at first: + # It corresponds to the next potential address that is 16bits or 32bits. + nextBlockAddr = regAddr + # Adjust the next block-address by respecting the alignment depending on the area + while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]: + nextBlockAddr += 1 + + mapping.blockDataSize = nextBlockAddr + # then compute the next block DB-number and return the current one + tmpblockAddress = mapping.blockAddress + # next absolute address: relies on the global class-address + mapping.blockAddress += (nbDev * mapping.blockDataSize) + # Count the number of block per area type, + # accumulate the block data size to compute the total device data size + mapping.nbBlock += 1 + mapping.deviceDataSize += mapping.blockDataSize + return mapping.classBaseAddress + tmpblockAddress + + # Block-address = offset in the device memory + def computeDeviceBlkAddressDefault(self, block, mapping, regAddr, nbDev): + # Compute block mem-size at first: + # it corresponds to the next potential address that is 16bits or 32bits + nextBlockAddr = regAddr + # Adjust the next block-address by respecting the alignment depending on the area + while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]: + nextBlockAddr += 1 + + mapping.blockDataSize = nextBlockAddr + # then compute the next block DB-number and return the current one + tmpblockAddress = mapping.blockAddress + # next relative address: independent from the global class-address + mapping.blockAddress += mapping.blockDataSize + # Count the number of block per area type, + # accumulate the block data size to compute the total device data size + mapping.nbBlock += 1 + mapping.deviceDataSize += mapping.blockDataSize + return tmpblockAddress + class SiemensController(Controller): def __init__(self, xmlNode): super(SiemensController, self).__init__(xmlNode) self.brand = "SIEMENS" - self.baseAddress = long(self.plcNode.prop('base-DB-number')) + self.computeAddresses() + + def computeDeviceInstAddress(self, mapping): + if not mapping.isDefined: + return mapping.instanceAddress + + tmpInstAddr = mapping.instanceAddress + mapping.instanceAddress += 1 #device DB-number + return tmpInstAddr + mapping.classBaseAddress + + def computeBlockInstAddress(self, mapping): + return self.computeBlockInstAddressDefault(mapping) + + def computeNextBaseAddress(self, mapping, nbDev): + mapping.usedData = "0 byte" + if not mapping.isDefined or ( mapping.nbBlock == 0 ) or not self.hasMappingFor(mapping.type): + return mapping.classBaseAddress + if mapping.type != MEM_TYPE: + return self.computeIONextBaseAddress(mapping, nbDev) + if self.protocol == self.BLOCK_MODE: + return self.computeBlockNextBaseAddress(mapping, nbDev) + elif self.protocol == self.DEVICE_MODE: + return self.computeDeviceNextBaseAddress(mapping, nbDev) + else: + raise Exception("The protocol '" + self.protocol + "' of controller '" + self.hostName + "is not known.") + # Compute the base DB-number of the next instance in the SIEMENS PLC memory + # BLOCK mode requires 1 DB per class block + def computeBlockNextBaseAddress(self, mapping, nbDev): + byteSize = nbDev * mapping.deviceDataSize + self.memSize = self.memSize + byteSize # global size of the plc configuration + startDB = mapping.classBaseAddress # first DB used for this class + self.memLast = mapping.classBaseAddress + mapping.nbBlock - 1 # last DB used + mapping.usedData = "DB%d..DB%d/%d bytes" % (startDB, self.memLast, byteSize) + mapping.classBaseAddress = self.memLast + 1 # next DB number + + # Compute the base DB-number of the next instance in the SIEMENS PLC memory + # DEVICE mode requires 1 DB per class instance + def computeDeviceNextBaseAddress(self, mapping, nbDev): + byteSize = nbDev * mapping.deviceDataSize + self.memSize = self.memSize + byteSize # global size of the plc configuration + startDB = mapping.classBaseAddress # first DB used for this class + self.memLast = mapping.classBaseAddress + nbDev - 1 # last DB used + mapping.usedData = "DB%d..DB%d/%d bytes" % (startDB, self.memLast, byteSize) + mapping.classBaseAddress = self.memLast + 1 # next DB number + + # Compute the base-address of the next class in the SIEMENS PLC IO area + # DEVICE or BLOCK mode use the same data size: next base address should be the same + # 'used-IO' info is expressed in bytes + def computeIONextBaseAddress(mapping, nbDev): + byteSize = nbDev * mapping.deviceDataSize + self.memSize += byteSize # global size of the plc configuration + startAddr = mapping.classBaseAddress # first byte address used for this class + self.memLast = startAddr + byteSize - 1 # last byte address used for this class + if mapping.type == DI_TYPE or mapping.type == AI_TYPE: + mapping.usedData = "IB%d..IB%d/%d bytes" % (startAddr, self.memLast, byteSize); + else: #in ['DO-', 'AO-'] + mapping.usedData = "QB%d..QB%d/%d bytes" % (startAddr, self.memLast, byteSize); + mapping.classBaseAddress = (mapping.classBaseAddress + byteSize) # next byte address expressed in bytes + + # Adjust the register relying on the SIEMENS Simatic alignment constraints + # MEMORY area: uses 8bits alignment except for array and >8bits data (16bits alignment) + # DIGITAL area: uses 8bit alignment without any exception. + # ANALOG area: uses 16bit alignment. + # In case of string, its length has to be +2 to hold info on string + def alignRegAddress(self, block, register, regAddress): + algnt = 8 + if ( block.isAnanlogIO() or ( block.isMEMBlock() and ((register.getDataSize() > 1) or (register.dim1 > 1) or (register.dim2 > 1) or (register.stringLength > 1))) ): + algnt = self.alligment[block.ioType] + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + if register.stringLength > 1: # register is a string, + if ((register.stringLength % 2) != 0): register.stringLength += 1 # adjusts the global size for byte type (word alignment) + register.stringLength += 2 # add increment to register.stringLength first two bytes for info on string (len, maxlen) + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + return regAddress + + def computeNextRegAddress(self, block, register, regAddress ): + regAddress = regAddress + self.msize; #compute the next address for any case + # SIEMENS requires specific treatment in case of array. + if register.isArrayType(): + #SIEMENS array is always followed by 16bits adressing + algnt = 16 + while(whichDataAlignment(regAddress) < algnt): + regAddress+=1 + + # SIEMENS ANALOG-IO area uses 16bit addressing + # SIEMENS MEMORY array is always followed by 16bits address + if block.isAnanlogIO() or ( block.isMEMBlock() and register.isArrayType() ): + while(whichDataAlignment(regAddress) < 16): + regAddress += 1 + return regAddress + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + if mapping.type == MEM_TYPE: + return self.computeBlockBlkAddressMemory(block, mapping, regAddr, nbDev) + else: + return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev) + + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev) + + # block-address = block DB-Number + def computeBlockBlkAddressMemory(self, block, mapping, regAddr, nbDev): + # Compute block mem-size at first: each block has a dedicated DB-number which contains an array of devices + # each element of the array is a structure which must be 16bits aligned! + nextBlockAddr = regAddr + # Adjust the next block-address by respecting the alignment depending on the area + while int(whichDataAlignment(nextBlockAddr)) < self.alligment[block.ioType]: + nextBlockAddr += 1 + mapping.blockDataSize = nextBlockAddr + # then compute the next block DB-number and return the current one + tmpblockAddress = mapping.blockAddress + mapping.blockAddress += 1 + # Count the number of block per area type, + # accumulate the block data size to compute the total device data size + mapping.nbBlock += 1 + mapping.deviceDataSize += mapping.blockDataSize + return mapping.classBaseAddress + tmpblockAddress + class BeckhoffController(Controller): addressFactor_default = 2 # Beckhoff default is 16 bit addressing - addressFactor_CX9020 = 1 - offset_default = 0 # No offset by default (Bus coupler for instance) - offset_BC9020 = 32768 # some controllers use a memory-offset - offset_CX9020 = 24576 + addressFactor_CX9020_Twincat2 = 1 + addressFactor_CX9020_Twincat3 = 2 + offset_mem_BC9020_base = 0x8000 # some controllers use a memory-offset + offset_mem_CX9020_base = 0x6000 + offset_output_base = 0x1000 # offset for analog and digital output registers + memoryAlignment_CX9020 = 32 def __init__(self, xmlNode): super(BeckhoffController, self).__init__(xmlNode) self.brand = "BECKHOFF" - self.baseAddress = long(self.plcNode.prop('base-address')) - self.addressFactor = self.addressFactor_default - self.offset = self.offset_default - if self.model == 'CX9020': - self.addressFactor = self.addressFactor_CX9020 - self.offset = self.offset_CX9020 + self.addressFactor = self.addressFactor_default + if 'CX90' in self.model: + if self.system == 'TWINCat-2': + self.addressFactor = self.addressFactor_CX9020_Twincat2 + elif self.system == 'TWINCat-3': + self.addressFactor = self.addressFactor_CX9020_Twincat3 + else: + raise Exception("system '" + self.system + "' of controller '" + self.hostName + "'not supported") + self.offset[MEM_TYPE] = self.offset_mem_CX9020_base / self.addressFactor + self.alligment[IOType.MEMORY] = self.memoryAlignment_CX9020 if self.model == 'BC9020': - self.offset = self.offset_BC9020 - self.baseAddress = ( self.baseAddress * self.addressFactor) + self.offset + self.offset[MEM_TYPE] = self.offset_mem_BC9020_base / self.addressFactor + self.offset[AO_TYPE] = self.offset_output_base / self.addressFactor + self.offset[DO_TYPE] = self.offset_output_base / self.addressFactor + self.computeAddresses() + + def computeDeviceInstAddress(self, mapping): + return self.computeDeviceInstAddressDefault(mapping) + + def computeBlockInstAddress(self, mapping): + return self.computeBlockInstAddressDefault(mapping) + + def computeNextBaseAddress(self, mapping, nbDev): + return self.computeNextBaseAddressDefault(mapping, nbDev) - + def alignRegAddress(self, block, register, regAddress): + if self.model == 'BC9020': + return self.alignBCxxRegAddress(block, register, regAddress); + elif self.model == 'CX9020': + return self.alignCXxxRegAddress(block, register, regAddress); + elif self.model == 'BK9000' or self.model == 'BK9050' or self.model == 'BK9100': + return self.alignRegAddressDefault(block, register, regAddress); + else: + raise Exception("The plc-model '" + self.model + "' is not yet supported.") + + # Adjust the register address relying on the BECKHOFF Twincat BC9020 alignment constraints. + # TwinCAT BCxx PLCs are 16bits processor and base-address is interpreted as 16bit address + # 8bits alignment between elements of 8bit-data array (including strings). + # In case of string, its length has to be +1 to hold end-terminator. + def alignBCxxRegAddress(self, block, register, regAddress): + algnt = 16 + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + if register.stringLength > 1: # register is a string, + register.stringLength += 1 # TwinCAT requires '\0' string terminator. + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + return regAddress + + # Adjust the register address relying on the BECKHOFF Twincat CX9020 alignment constraints. + # TwinCAT CXxx PLCs are 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping) + # TWINCAT-2: 32bits alignment except for 8/16bits (16bits alignment). + # TWINCAT-3: 16bits alignment + # BOTH: 8bits alignment between elements of 8bit-data array (including strings). + # In case of string, its length has to be +1 to hold end-terminator. + def alignCXxxRegAddress(self, block, register, regAddress): + algnt = 16 + if (register.getDataSize() > 2): + algnt = self.alligment[block.ioType] #depends on TwinCAT platform + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + if register.stringLength > 1: # register is a string, + register.stringLength += 1 # TwinCAT requires '\0' string terminator. + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + return regAddress + + def computeNextRegAddress(self, block, register, regAddress): + return self.computeNextRegAddressDefault(block, register, regAddress) + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev) + + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev) + class SchneiderController(Controller): - addressFactor = 2 # Premium/Quantum uses 16bit adressing for 32bit values # Unity M340 is interpreted as 32bit address + addressFactor_Schneider_default = 2 + memoryAlignment_M340 = 32 def __init__(self, xmlNode): super(SchneiderController, self).__init__(xmlNode) self.brand = "SCHNEIDER" - self.baseAddress = long(self.plcNode.prop('base-address')) - self.baseAddress = self.baseAddress * self.addressFactor + self.addressFactor = self.addressFactor_Schneider_default + if self.model == 'M340': + self.alligment[IOType.MEMORY] = self.memoryAlignment_M340 + self.computeAddresses() + + def computeDeviceInstAddress(self, mapping): + return self.computeDeviceInstAddressDefault(mapping) + + def computeBlockInstAddress(self, mapping): + return self.computeBlockInstAddressDefault(mapping) + + def computeNextBaseAddress(self, mapping, nbDev): + return self.computeNextBaseAddressDefault(mapping, nbDev) + + def alignRegAddress(self, block, register, regAddress): + if self.model == 'M340': + return self.alignM340RegAddress(block, register, regAddress); + elif self.model == 'Premium' or self.model == 'Quantum': + return self.alignRegAddressDefault(block, register, regAddress); + else: + raise Exception("The plc-model '" + self.model + "' is not yet supported.") + # Adjust the register address relying on the SCHNEIDER M340 alignment constraints + # Unity M340 is 32bits processor but base-address is interpreted as 16bit address (required even address in the mapping) + # 32bits alignment except for 8/16bits (16bits alignment) + # Byte elements of array (including STRING) use 8bit alignment. + + def alignM340RegAddress(self, block, register, regAddress): + algnt = 16 + if (register.getDataSize() > 2): + algnt = self.alligment[block.ioType] + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + if register.format == 'int8' or register.format == 'char':# 8bit signed type use word alignment (16bit) + self.msize = self.msize * 2 # while string and uint8-array use 8bit alignment + return regAddress + + def computeNextRegAddress(self, block, register, regAddress): + return self.computeNextRegAddressDefault(block, register, regAddress) + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev) + + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev) + class RabbitController(Controller): - addressFactor = 2 + addressFactor_DIGI_default = 2 def __init__(self, xmlNode): super(RabbitController, self).__init__(xmlNode) self.brand = "DIGI" - self.baseAddress = long(self.plcNode.prop('base-address')) - self.baseAddress = self.baseAddress * self.addressFactor + self.addressFactor = self.addressFactor_DIGI_default + self.computeAddresses() + + def computeDeviceInstAddress(self, mapping): + return self.computeDeviceInstAddressDefault(mapping) + + def computeBlockInstAddress(self, mapping): + return self.computeBlockInstAddressDefault(mapping) + + def computeNextBaseAddress(self, mapping, nbDev): + return self.computeNextBaseAddressDefault(mapping, nbDev) + + # Adjust the register address relying on the DIGI-Rabbit RCMx alignment constraints + # Use 16bits processor and base-address is interpreted as 16bit address + def alignRegAddress(self, block, register, regAddress): + algnt = 16 + while(whichDataAlignment(regAddress) < algnt): + regAddress += 1 + self.msize = register.dim1 * register.dim2 * register.stringLength * register.getDataSize() # compute memory data size + if not register.isStringType(): + if (register.getDataSize() == 1): # but it's a 8bit type + self.msize = self.msize * 2 # so, it's a word alignment (only string use byte alignment) + return regAddress + + def computeNextRegAddress(self, block, register, regAddress): + return self.computeNextRegAddressDefault(block, register, regAddress) + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeBlockBlkAddressDefault(block, mapping, regAddr, nbDev) + + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + return self.computeDeviceBlkAddressDefault(block, mapping, regAddr, nbDev) -class VirtualS7Controller(Controller): - def __init__(self, xmlNode): - super(VirtualS7Controller, self).__init__(xmlNode) - self.brand = "SIEMENS" - self.baseAddress = long(self.plcNode.prop('base-address')) - class NIController(Controller): def __init__(self, xmlNode): super(NIController, self).__init__(xmlNode) self.brand = "NI" - self.baseAddress = 0 + self.computeAddresses() + def computeDeviceInstAddress(self, mapping): + return 0 + + def computeNextBaseAddress(self, mapping, nbDev): + mapping.usedData = "0 byte" + mapping.classBaseAddress = 0 + + def alignRegAddress(self, block, register, regAddress): + return self.regCounter + + def computeNextRegAddress(self, block, register, regAddress): + regAddress = regAddress + self.msize; #compute the next address for any case + self.msize = 0 + return regAddress + + def computeBlockBlkAddress(self, block, mapping, regAddr, nbDev): + raise Exception("Block-mode not possible for NI-Controllers") + def computeDeviceBlkAddress(self, block, mapping, regAddr, nbDev): + self.blockCounter += 1 + # Count the number of block per area type, + # accumulate the block data size to compute the total device data size + mapping.nbBlock += 1 + mapping.deviceDataSize += mapping.blockDataSize + return self.blockCounter #xmlNode.shellPrintNode() diff --git a/silecs-codegen/src/xml/model/Param/Controller.py b/silecs-codegen/src/xml/model/Param/Controller.py index f56606e6ecb5c1a2a79c8205087d15d7e63be0df..5cd2e33c8a6c0f9284689de9da81f03fa2cc133b 100644 --- a/silecs-codegen/src/xml/model/Param/Controller.py +++ b/silecs-codegen/src/xml/model/Param/Controller.py @@ -16,6 +16,7 @@ from model.Class.Class import ParamClass from model.Deploy.Controller import Controller +from Mapping import * import libxml2 class ParamController(object): @@ -27,7 +28,7 @@ class ParamController(object): self.model = "" self.protocol = "" self.brand = "" - self.address = long(0) + self.address = { MEM_TYPE: long(-1), DI_TYPE: long(-1), DO_TYPE: long(-1), AI_TYPE: long(-1), AO_TYPE: long(-1) } self.usedMem = "" self.xmlNode = None self.paramClasses = [] @@ -40,7 +41,11 @@ class ParamController(object): self.model = self.xmlNode.prop('plc-model') self.protocol = self.xmlNode.prop('protocol') self.brand = self.xmlNode.prop("plc-brand") - self.address = long(self.xmlNode.prop("address")) + self.address[MEM_TYPE] = long(self.xmlNode.prop("address")) + self.address[DI_TYPE] = long(self.xmlNode.prop("DI-address")) + self.address[DO_TYPE] = long(self.xmlNode.prop("DO-address")) + self.address[AI_TYPE] = long(self.xmlNode.prop("AI-address")) + self.address[AO_TYPE] = long(self.xmlNode.prop("AO-address")) self.usedMem = self.xmlNode.prop("used-mem") def initFromXMLNode(self, xmlNode): @@ -57,7 +62,12 @@ class ParamController(object): newNode.newProp("plc-system", str(controller.system)) newNode.newProp("plc-model", controller.model) newNode.newProp("protocol", controller.protocol) - newNode.newProp("address", str(controller.baseAddress)) + newNode.newProp("address", str(controller.address[MEM_TYPE])) + newNode.newProp("DI-address", str(controller.address[DI_TYPE])) + newNode.newProp("DO-address", str(controller.address[DO_TYPE])) + newNode.newProp("AI-address", str(controller.address[AI_TYPE])) + newNode.newProp("AO-address", str(controller.address[AO_TYPE])) + newNode.newProp("domain", controller.domain) newNode.newProp("used-mem", "TODO") self.initAttributes(newNode) diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy index 0c5dbffbf80c077a1484af4416efda8412ad3606..ae92f5a229a1eef3b1e37d9022ef65c21cf78c65 100644 --- a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy +++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy @@ -37,32 +37,37 @@ </Controller> <Controller host-name="Virtual_SiemensDevice"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="DEVICE_MODE" base-address="0"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" protocol="DEVICE_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> </Virtual-Controller> </Controller> <Controller host-name="Virtual_SiemensBlock"> - <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="BLOCK_MODE" base-address="0"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="SNAP7 linux32" protocol="BLOCK_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> </Virtual-Controller> </Controller> <Controller host-name="Beckhoff_BC9020"> - <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> + <Beckhoff-PLC model="BC9020" system="TWINCat-2" protocol="BLOCK_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> </Beckhoff-PLC> </Controller> - <Controller host-name="Beckhoff_CX9020"> - <Beckhoff-PLC model="CX9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> + <Controller host-name="Beckhoff_CX9020_TC2"> + <Beckhoff-PLC model="CX9020" system="TWINCat-2" protocol="BLOCK_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> </Beckhoff-PLC> - </Controller> + <Controller host-name="Beckhoff_CX9020_TC3"> + <Beckhoff-PLC model="CX9020" system="TWINCat-3" protocol="BLOCK_MODE" base-address="0"> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> + <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> + </Beckhoff-PLC> + </Controller> <Controller host-name="Schneider_PremiumQuantum"> <Schneider-PLC model="Premium" system="UNITY Pro" protocol="BLOCK_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> diff --git a/silecs-codegen/src/xml/test/general/genParamTest.py b/silecs-codegen/src/xml/test/general/genParamTest.py index 64f955bf9cd14b44d6f7d72e9187b55801cfeb5a..0cc31d1ef533593d047b7228f976c5d5ac0f8e3f 100644 --- a/silecs-codegen/src/xml/test/general/genParamTest.py +++ b/silecs-codegen/src/xml/test/general/genParamTest.py @@ -59,7 +59,8 @@ def SiemensVirtualSourcesTest(): def BeckhoffSourcesTest(): CompareGeneratedFiles("Beckhoff_BC9020",".silecsparam") - CompareGeneratedFiles("Beckhoff_CX9020",".silecsparam") + CompareGeneratedFiles("Beckhoff_CX9020_TC2",".silecsparam") + CompareGeneratedFiles("Beckhoff_CX9020_TC3",".silecsparam") def SchneiderSourcesTest(): CompareGeneratedFiles("Schneider_M340",".silecsparam") diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py index ad97feae26ac5f224e401d1f3119cf17944c1802..7262d6a2d106f74ccc23e4adb97f0c58e020fce4 100644 --- a/silecs-codegen/src/xml/test/general/genplcsrcTest.py +++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py @@ -77,7 +77,8 @@ def SiemensVirtualSourcesTest(): def BeckhoffSourcesTest(): CompareGeneratedFiles("Beckhoff_BC9020",".exp") - CompareGeneratedFiles("Beckhoff_CX9020",".exp") + CompareGeneratedFiles("Beckhoff_CX9020_TC2",".exp") + CompareGeneratedFiles("Beckhoff_CX9020_TC3",".exp") def SchneiderSourcesTest(): CompareGeneratedFiles("Schneider_M340",".xsy") diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam index 2b7c148e2f8ca1b910021ad2bfe855c3a30ead0c..11250f892fda94f20b88d15e682c0e7eb4e7ca9c 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_BC9020.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.492677"/> + <Generation date="2017-07-27 16:14:06.421145"/> <Deployment checksum="1037751963"/> </Mapping-Info> - <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" usedMemory="MW16384..MW16407 / 24 words"> + <SILECS-Mapping plc-name="Beckhoff_BC9020" plc-brand="BECKHOFF" plc-system="TWINCat-2" plc-model="BC9020" protocol="BLOCK_MODE" address="32768" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="32768" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW23/24 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="32768" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="17"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="32816" usedMemory="MW16408..MW18215 / 1808 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="32816" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW24..MW1783/1760 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="32816" mem-size="122"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam similarity index 92% rename from silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam rename to silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam index 20aae0aa31382d8a444f44c6c3ed814e9747412d..b1393097bbd7f2a35ad1856383fca7b84ca5cd34 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC2.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.530253"/> + <Generation date="2017-07-28 12:11:45.390885"/> <Deployment checksum="2754857673"/> </Mapping-Info> - <SILECS-Mapping plc-name="Beckhoff_CX9020" plc-brand="BECKHOFF" plc-system="TWINCat" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" usedMemory="MW12288..MW12313 / 26 words"> + <SILECS-Mapping plc-name="Beckhoff_CX9020_TC2" plc-brand="BECKHOFF" plc-system="TWINCat-2" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW51/52 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="24576" mem-size="52"> <Acquisition-Register name="_version" size="1" address="0" mem-size="17"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="24628" usedMemory="MW12314..MW14133 / 1820 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="24628" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW52..MW3587/3536 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="24628" mem-size="128"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam new file mode 100644 index 0000000000000000000000000000000000000000..069dc75fc1f2c7ae305944aacd40f23d60757d87 --- /dev/null +++ b/silecs-codegen/src/xml/test/generated_correct/client/Beckhoff_CX9020_TC3.silecsparam @@ -0,0 +1,190 @@ +<?xml version="1.0"?> +<SILECS-Param silecs-version="DEV"> + <Mapping-Info> + <Owner user-login="schwinn"/> + <Generation date="2017-07-28 12:11:45.427012"/> + <Deployment checksum="2754857673"/> + </Mapping-Info> + <SILECS-Mapping plc-name="Beckhoff_CX9020_TC3" plc-brand="BECKHOFF" plc-system="TWINCat-3" plc-model="CX9020" protocol="BLOCK_MODE" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="24576" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW25/26 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> + <Acquisition-Block name="hdrBlk" size="14" address="24576" mem-size="52"> + <Acquisition-Register name="_version" size="1" address="0" mem-size="17"> + <string string-length="16" format="string"/> + </Acquisition-Register> + <Acquisition-Register name="_checksum" size="4" address="20" mem-size="4"> + <scalar format="uint32"/> + </Acquisition-Register> + <Acquisition-Register name="_user" size="1" address="24" mem-size="17"> + <string string-length="16" format="string"/> + </Acquisition-Register> + <Acquisition-Register name="_date" size="8" address="44" mem-size="8"> + <scalar format="dt"/> + </Acquisition-Register> + </Acquisition-Block> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + </SILECS-Class> + <SILECS-Class name="AllTypes" version="0.1.0" address="24628" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW26..MW1793/1768 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> + <Acquisition-Block name="MyROBlock" size="53" address="24628" mem-size="128"> + <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> + <scalar format="int8"/> + </Acquisition-Register> + <Acquisition-Register name="RO_uint8" generateFesaValueItem="true" fesaFieldName="RO_uint8_fesa" size="1" address="2" mem-size="1"> + <scalar format="uint8"/> + </Acquisition-Register> + <Acquisition-Register name="RO_int16" generateFesaValueItem="true" fesaFieldName="RO_int16_fesa" size="2" address="4" mem-size="2"> + <scalar format="int16"/> + </Acquisition-Register> + <Acquisition-Register name="RO_uint16" generateFesaValueItem="true" fesaFieldName="RO_uint16_fesa" size="2" address="6" mem-size="2"> + <scalar format="uint16"/> + </Acquisition-Register> + <Acquisition-Register name="RO_int32" generateFesaValueItem="true" fesaFieldName="RO_int32_fesa" size="4" address="8" mem-size="4"> + <scalar format="int32"/> + </Acquisition-Register> + <Acquisition-Register name="RO_uint32" generateFesaValueItem="true" fesaFieldName="RO_uint32_fesa" size="4" address="12" mem-size="4"> + <scalar format="uint32"/> + </Acquisition-Register> + <Acquisition-Register name="RO_float32" generateFesaValueItem="true" fesaFieldName="RO_float32_fesa" size="4" address="16" mem-size="4"> + <scalar format="float32"/> + </Acquisition-Register> + <Acquisition-Register name="RO_string" generateFesaValueItem="true" fesaFieldName="RO_string_fesa" size="1" address="20" mem-size="65"> + <string string-length="64" format="string"/> + </Acquisition-Register> + <Acquisition-Register name="RO_date" generateFesaValueItem="true" fesaFieldName="RO_date_fesa" size="8" address="88" mem-size="8"> + <scalar format="date"/> + </Acquisition-Register> + <Acquisition-Register name="RO_char" generateFesaValueItem="true" fesaFieldName="RO_char_fesa" size="1" address="96" mem-size="1"> + <scalar format="char"/> + </Acquisition-Register> + <Acquisition-Register name="RO_byte" generateFesaValueItem="true" fesaFieldName="RO_byte_fesa" size="1" address="98" mem-size="1"> + <scalar format="byte"/> + </Acquisition-Register> + <Acquisition-Register name="RO_word" generateFesaValueItem="true" fesaFieldName="RO_word_fesa" size="2" address="100" mem-size="2"> + <scalar format="word"/> + </Acquisition-Register> + <Acquisition-Register name="RO_dword" generateFesaValueItem="true" fesaFieldName="RO_dword_fesa" size="4" address="104" mem-size="4"> + <scalar format="dword"/> + </Acquisition-Register> + <Acquisition-Register name="RO_int" generateFesaValueItem="true" fesaFieldName="RO_int_fesa" size="2" address="108" mem-size="2"> + <scalar format="int"/> + </Acquisition-Register> + <Acquisition-Register name="RO_dint" generateFesaValueItem="true" fesaFieldName="RO_dint_fesa" size="4" address="112" mem-size="4"> + <scalar format="dint"/> + </Acquisition-Register> + <Acquisition-Register name="RO_real" generateFesaValueItem="true" fesaFieldName="RO_real_fesa" size="4" address="116" mem-size="4"> + <scalar format="real"/> + </Acquisition-Register> + <Acquisition-Register name="RO_dt" generateFesaValueItem="true" fesaFieldName="RO_dt_fesa" size="8" address="120" mem-size="8"> + <scalar format="dt"/> + </Acquisition-Register> + </Acquisition-Block> + <Setting-Block name="MyRWBlock" size="212" address="24884" mem-size="468"> + <Volatile-Register name="RW_int8" generateFesaValueItem="true" size="1" address="0" mem-size="4"> + <array2D dim1="2" dim2="2" format="int8"/> + </Volatile-Register> + <Volatile-Register name="RW_uint8" generateFesaValueItem="true" fesaFieldName="RW_uint8_fesa" size="1" address="4" mem-size="4"> + <array2D dim1="2" dim2="2" format="uint8"/> + </Volatile-Register> + <Volatile-Register name="RW_int16" generateFesaValueItem="true" fesaFieldName="RW_int16_fesa" size="2" address="8" mem-size="8"> + <array2D dim1="2" dim2="2" format="int16"/> + </Volatile-Register> + <Volatile-Register name="RW_uint16" generateFesaValueItem="true" fesaFieldName="RW_uint16_fesa" size="2" address="16" mem-size="8"> + <array2D dim1="2" dim2="2" format="uint16"/> + </Volatile-Register> + <Volatile-Register name="RW_int32" generateFesaValueItem="true" fesaFieldName="RW_int32_fesa" size="4" address="24" mem-size="16"> + <array2D dim1="2" dim2="2" format="int32"/> + </Volatile-Register> + <Volatile-Register name="RW_uint32" generateFesaValueItem="true" fesaFieldName="RW_uint32_fesa" size="4" address="40" mem-size="16"> + <array2D dim1="2" dim2="2" format="uint32"/> + </Volatile-Register> + <Volatile-Register name="RW_float32" generateFesaValueItem="true" fesaFieldName="RW_float32_fesa" size="4" address="56" mem-size="16"> + <array2D dim1="2" dim2="2" format="float32"/> + </Volatile-Register> + <Volatile-Register name="RW_string" generateFesaValueItem="true" fesaFieldName="RW_string_fesa" size="1" address="72" mem-size="260"> + <stringArray2D dim1="2" dim2="2" string-length="64" format="string"/> + </Volatile-Register> + <Volatile-Register name="RW_date" generateFesaValueItem="true" fesaFieldName="RW_date_fesa" size="8" address="332" mem-size="32"> + <array2D dim1="2" dim2="2" format="date"/> + </Volatile-Register> + <Volatile-Register name="RW_char" generateFesaValueItem="true" fesaFieldName="RW_char_fesa" size="1" address="364" mem-size="4"> + <array2D dim1="2" dim2="2" format="char"/> + </Volatile-Register> + <Volatile-Register name="RW_byte" generateFesaValueItem="true" fesaFieldName="RW_byte_fesa" size="1" address="368" mem-size="4"> + <array2D dim1="2" dim2="2" format="byte"/> + </Volatile-Register> + <Volatile-Register name="RW_word" generateFesaValueItem="true" fesaFieldName="RW_word_fesa" size="2" address="372" mem-size="8"> + <array2D dim1="2" dim2="2" format="word"/> + </Volatile-Register> + <Volatile-Register name="RW_dword" generateFesaValueItem="true" fesaFieldName="RW_dword_fesa" size="4" address="380" mem-size="16"> + <array2D dim1="2" dim2="2" format="dword"/> + </Volatile-Register> + <Volatile-Register name="RW_int" generateFesaValueItem="true" fesaFieldName="RW_int_fesa" size="2" address="396" mem-size="8"> + <array2D dim1="2" dim2="2" format="int"/> + </Volatile-Register> + <Volatile-Register name="RW_dint" generateFesaValueItem="true" fesaFieldName="RW_dint_fesa" size="4" address="404" mem-size="16"> + <array2D dim1="2" dim2="2" format="dint"/> + </Volatile-Register> + <Volatile-Register name="RW_real" generateFesaValueItem="true" fesaFieldName="RW_real_fesa" size="4" address="420" mem-size="16"> + <array2D dim1="2" dim2="2" format="real"/> + </Volatile-Register> + <Volatile-Register name="RW_dt" generateFesaValueItem="true" fesaFieldName="RW_dt_fesa" size="8" address="436" mem-size="32"> + <array2D dim1="2" dim2="2" format="dt"/> + </Volatile-Register> + </Setting-Block> + <Command-Block name="MyWOBlock" size="530" address="25820" mem-size="1172"> + <Setting-Register name="WO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="10"> + <array dim="10" format="int8"/> + </Setting-Register> + <Setting-Register name="WO_uint8" generateFesaValueItem="true" fesaFieldName="WO_uint8_fesa" size="1" address="10" mem-size="10"> + <array dim="10" format="uint8"/> + </Setting-Register> + <Setting-Register name="WO_int16" generateFesaValueItem="true" fesaFieldName="WO_int16_fesa" size="2" address="20" mem-size="20"> + <array dim="10" format="int16"/> + </Setting-Register> + <Setting-Register name="WO_uint16" generateFesaValueItem="true" fesaFieldName="WO_uint16_fesa" size="2" address="40" mem-size="20"> + <array dim="10" format="uint16"/> + </Setting-Register> + <Setting-Register name="WO_int32" generateFesaValueItem="true" fesaFieldName="WO_int32_fesa" size="4" address="60" mem-size="40"> + <array dim="10" format="int32"/> + </Setting-Register> + <Setting-Register name="WO_uint32" generateFesaValueItem="true" fesaFieldName="WO_uint32_fesa" size="4" address="100" mem-size="40"> + <array dim="10" format="uint32"/> + </Setting-Register> + <Setting-Register name="WO_float32" generateFesaValueItem="true" fesaFieldName="WO_float32_fesa" size="4" address="140" mem-size="40"> + <array dim="10" format="float32"/> + </Setting-Register> + <Setting-Register name="WO_string" generateFesaValueItem="true" fesaFieldName="WO_string_fesa" size="1" address="180" mem-size="650"> + <stringArray dim="10" string-length="64" format="string"/> + </Setting-Register> + <Setting-Register name="WO_date" generateFesaValueItem="true" fesaFieldName="WO_date_fesa" size="8" address="832" mem-size="80"> + <array dim="10" format="date"/> + </Setting-Register> + <Setting-Register name="WO_char" generateFesaValueItem="true" fesaFieldName="WO_char_fesa" size="1" address="912" mem-size="10"> + <array dim="10" format="char"/> + </Setting-Register> + <Setting-Register name="WO_byte" generateFesaValueItem="true" fesaFieldName="WO_byte_fesa" size="1" address="922" mem-size="10"> + <array dim="10" format="byte"/> + </Setting-Register> + <Setting-Register name="WO_word" generateFesaValueItem="true" fesaFieldName="WO_word_fesa" size="2" address="932" mem-size="20"> + <array dim="10" format="word"/> + </Setting-Register> + <Setting-Register name="WO_dword" generateFesaValueItem="true" fesaFieldName="WO_dword_fesa" size="4" address="952" mem-size="40"> + <array dim="10" format="dword"/> + </Setting-Register> + <Setting-Register name="WO_int" generateFesaValueItem="true" fesaFieldName="WO_int_fesa" size="2" address="992" mem-size="20"> + <array dim="10" format="int"/> + </Setting-Register> + <Setting-Register name="WO_dint" generateFesaValueItem="true" fesaFieldName="WO_dint_fesa" size="4" address="1012" mem-size="40"> + <array dim="10" format="dint"/> + </Setting-Register> + <Setting-Register name="WO_real" generateFesaValueItem="true" fesaFieldName="WO_real_fesa" size="4" address="1052" mem-size="40"> + <array dim="10" format="real"/> + </Setting-Register> + <Setting-Register name="WO_dt" generateFesaValueItem="true" fesaFieldName="WO_dt_fesa" size="8" address="1092" mem-size="80"> + <array dim="10" format="dt"/> + </Setting-Register> + </Command-Block> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + </SILECS-Class> + </SILECS-Mapping> +</SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam index 5e445be2729b9b49c9e7a49037d0b3859c68614b..547f7eff5ee62111d0793ecfa54214bde2bd7205 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_BlockMode.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.682209"/> + <Generation date="2017-07-27 16:14:06.611199"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> + <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1821/1800 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="120"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam index d9946854f1f85aaa04950cc45ced9af8b7e72c58..8405a9d5208473a1a478ac8d5f48464348b03cd4 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Rabbit_DeviceMode.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.645862"/> + <Generation date="2017-07-27 16:14:06.572989"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> + <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="DIGI" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1865 / 1844 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1821/1800 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="120"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="44"/> - <Instance label="testDevice2" address="1888"/> + <Instance label="testDevice1" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1844" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam index 2287afacfda1278ad945b0525987f6f6d9c0cf82..9f487f777f7fcddc30fa5a63c5975872ecec5f23 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_M340.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.607123"/> + <Generation date="2017-07-27 16:14:06.534996"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> + <SILECS-Mapping plc-name="Schneider_M340" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="M340" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1845 / 1824 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1801/1780 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="124"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam index 986aa092bcffc51ef28d375fddf91181a39ea505..a8fc93ad660871337aac9b155c074dc1b8272bf1 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Schneider_PremiumQuantum.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.568077"/> + <Generation date="2017-07-27 16:14:06.499570"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="MW0..MW21 / 22 words"> + <SILECS-Mapping plc-name="Schneider_PremiumQuantum" plc-brand="SCHNEIDER" plc-system="UNITY Pro" plc-model="Premium" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW0..MW21/22 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="44" usedMemory="MW22..MW1837 / 1816 words"> + <SILECS-Class name="AllTypes" version="0.1.0" address="44" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="MW22..MW1793/1772 words" used-DI="0 word" used-DO="0 word" used-AI="0 word" used-AO="0 word"> <Acquisition-Block name="MyROBlock" size="53" address="44" mem-size="120"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="2"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam index f6ad542a588ece820a32b2b955f07b428341ea49..9537336121eecb9417336884bf9d9625186156ad 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Block.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.340140"/> + <Generation date="2017-07-27 16:14:06.268832"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Siemens_Step7Block" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="1"/> - <Instance label="testDevice2" address="2"/> + <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam index 11ab3a4d92ab05eca142cfd2c5a93c88d1383ae4..9202eb91813b47c501ab822144d6703e0093cd93 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_Step7Device.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.378125"/> + <Generation date="2017-07-27 16:14:06.306171"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Siemens_Step7Device" plc-brand="SIEMENS" plc-system="STEP-7" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam index aedddec1cda9f200133797bbf8bcca84edcacd54..b861f907cae5a433a52e63377a61a5eeb3504906 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaBlock.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.302895"/> + <Generation date="2017-07-27 16:14:06.229930"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Siemens_TiaBlock" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam index a9a789de36fc615490246577d62d81dfd19d3b4e..61c75903977e855dc18dda006c3e1f2677b70bc3 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Siemens_TiaDevice.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.263419"/> + <Generation date="2017-07-27 16:14:06.192160"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Siemens_TiaDevice" plc-brand="SIEMENS" plc-system="TIA-PORTAL" plc-model="SIMATIC_S7-300" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="1"/> - <Instance label="testDevice2" address="2"/> + <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam index ef0b905083157b6e3d405f57a01df635ca8a136e..abb3a74ecfcb34fd9d3c8d52e5fb9f476002e8c8 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensBlock.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.453248"/> + <Generation date="2017-07-28 12:09:58.078995"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Virtual_SiemensBlock" plc-brand="SIEMENS" plc-system="S7 virtual controller" plc-model="SIMATIC_S7-VIRTUAL" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Virtual_SiemensBlock" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="BLOCK_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB3 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB3/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="1" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="0"/> - <Instance label="testDevice2" address="1"/> + <Instance label="testDevice1" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam index 61c9023b07a337a325d273732268fe0784d999c8..de610430ebacc1a6630146f104dafaeab1c258c0 100644 --- a/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam +++ b/silecs-codegen/src/xml/test/generated_correct/client/Virtual_SiemensDevice.silecsparam @@ -2,11 +2,11 @@ <SILECS-Param silecs-version="DEV"> <Mapping-Info> <Owner user-login="schwinn"/> - <Generation date="2017-07-25 11:00:26.415203"/> + <Generation date="2017-07-28 12:09:58.040528"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Virtual_SiemensDevice" plc-brand="SIEMENS" plc-system="S7 virtual controller" plc-model="SIMATIC_S7-VIRTUAL" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> - <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" usedMemory="DB0..DB0 / 48 bytes"> + <SILECS-Mapping plc-name="Virtual_SiemensDevice" plc-brand="SIEMENS" plc-system="SNAP7 linux32" plc-model="SIMATIC_S7-VIRTUAL" protocol="DEVICE_MODE" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" domain="" used-mem="TODO"> + <SILECS-Class name="SilecsHeader" version="1.0.0" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB0..DB0/48 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="48"> <Acquisition-Register name="_version" size="1" address="0" mem-size="18"> <string string-length="16" format="string"/> @@ -21,9 +21,9 @@ <scalar format="dt"/> </Acquisition-Register> </Acquisition-Block> - <Instance label="SilecsHeader" address="0"/> + <Instance label="SilecsHeader" address="0" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> - <SILECS-Class name="AllTypes" version="0.1.0" address="1" usedMemory="DB1..DB2 / 3636 bytes"> + <SILECS-Class name="AllTypes" version="0.1.0" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1" used-mem="DB1..DB2/3540 bytes" used-DI="0 byte" used-DO="0 byte" used-AI="0 byte" used-AO="0 byte"> <Acquisition-Block name="MyROBlock" size="53" address="0" mem-size="118"> <Acquisition-Register name="RO_int8" generateFesaValueItem="true" size="1" address="0" mem-size="1"> <scalar format="int8"/> @@ -183,8 +183,8 @@ <array dim="10" format="dt"/> </Setting-Register> </Command-Block> - <Instance label="testDevice1" address="1"/> - <Instance label="testDevice2" address="2"/> + <Instance label="testDevice1" address="1" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> + <Instance label="testDevice2" address="2" DI-address="-1" DO-address="-1" AI-address="-1" AO-address="-1"/> </SILECS-Class> </SILECS-Mapping> </SILECS-Param> diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp similarity index 96% rename from silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp rename to silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp index d6fca4ca68637ac60952990e7de60bbdeb1bfe47..7b1e2a3ef9e1df24cb96bbf1fbd3b9dcdcacb328 100644 --- a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020.exp +++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC2.exp @@ -17,7 +17,7 @@ VAR_GLOBAL _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn'; (*SilecsHeader/SilecsHeader/hdrBlk *) - _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-6-8-16:38:3; + _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-7-28-12:15:6; (*AllTypes/testDevice1/MyROBlock *) RO_int8_a583_testDevice1 AT %MW52: SINT; diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp new file mode 100644 index 0000000000000000000000000000000000000000..7b1e2a3ef9e1df24cb96bbf1fbd3b9dcdcacb328 --- /dev/null +++ b/silecs-codegen/src/xml/test/generated_correct/controller/Beckhoff_CX9020_TC3.exp @@ -0,0 +1,328 @@ +(* +------------------------------------------------------------------- +* | C.E.R.N Geneva, Switzerland +* | SILECS - BE/CO-FE +* | April 2015 +* +------------------------------------------------------------------- +* +* Release : SILECS_DEV +*) +VAR_GLOBAL + (*SilecsHeader/SilecsHeader/hdrBlk *) + _version_a781_SilecsHeader AT %MW0: STRING(16):= DEV; + + (*SilecsHeader/SilecsHeader/hdrBlk *) + _checksum_a781_SilecsHeader AT %MW20: DWORD:= 2754857673; + + (*SilecsHeader/SilecsHeader/hdrBlk *) + _user_a781_SilecsHeader AT %MW24: STRING(16):= 'schwinn'; + + (*SilecsHeader/SilecsHeader/hdrBlk *) + _date_a781_SilecsHeader AT %MW44: DT:= DT#2017-7-28-12:15:6; + + (*AllTypes/testDevice1/MyROBlock *) + RO_int8_a583_testDevice1 AT %MW52: SINT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_uint8_a583_testDevice1 AT %MW54: BYTE; + + (*AllTypes/testDevice1/MyROBlock *) + RO_int16_a583_testDevice1 AT %MW56: INT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_uint16_a583_testDevice1 AT %MW58: WORD; + + (*AllTypes/testDevice1/MyROBlock *) + RO_int32_a583_testDevice1 AT %MW60: DINT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_uint32_a583_testDevice1 AT %MW64: DWORD; + + (*AllTypes/testDevice1/MyROBlock *) + RO_float32_a583_testDevice1 AT %MW68: REAL; + + (*AllTypes/testDevice1/MyROBlock *) + RO_string_a583_testDevice1 AT %MW72: STRING(64); + + (*AllTypes/testDevice1/MyROBlock *) + RO_date_a583_testDevice1 AT %MW140: DT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_char_a583_testDevice1 AT %MW148: SINT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_byte_a583_testDevice1 AT %MW150: BYTE; + + (*AllTypes/testDevice1/MyROBlock *) + RO_word_a583_testDevice1 AT %MW152: WORD; + + (*AllTypes/testDevice1/MyROBlock *) + RO_dword_a583_testDevice1 AT %MW156: DWORD; + + (*AllTypes/testDevice1/MyROBlock *) + RO_int_a583_testDevice1 AT %MW160: INT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_dint_a583_testDevice1 AT %MW164: DINT; + + (*AllTypes/testDevice1/MyROBlock *) + RO_real_a583_testDevice1 AT %MW168: REAL; + + (*AllTypes/testDevice1/MyROBlock *) + RO_dt_a583_testDevice1 AT %MW172: DT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_int8_a583_testDevice2 AT %MW180: SINT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_uint8_a583_testDevice2 AT %MW182: BYTE; + + (*AllTypes/testDevice2/MyROBlock *) + RO_int16_a583_testDevice2 AT %MW184: INT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_uint16_a583_testDevice2 AT %MW186: WORD; + + (*AllTypes/testDevice2/MyROBlock *) + RO_int32_a583_testDevice2 AT %MW188: DINT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_uint32_a583_testDevice2 AT %MW192: DWORD; + + (*AllTypes/testDevice2/MyROBlock *) + RO_float32_a583_testDevice2 AT %MW196: REAL; + + (*AllTypes/testDevice2/MyROBlock *) + RO_string_a583_testDevice2 AT %MW200: STRING(64); + + (*AllTypes/testDevice2/MyROBlock *) + RO_date_a583_testDevice2 AT %MW268: DT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_char_a583_testDevice2 AT %MW276: SINT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_byte_a583_testDevice2 AT %MW278: BYTE; + + (*AllTypes/testDevice2/MyROBlock *) + RO_word_a583_testDevice2 AT %MW280: WORD; + + (*AllTypes/testDevice2/MyROBlock *) + RO_dword_a583_testDevice2 AT %MW284: DWORD; + + (*AllTypes/testDevice2/MyROBlock *) + RO_int_a583_testDevice2 AT %MW288: INT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_dint_a583_testDevice2 AT %MW292: DINT; + + (*AllTypes/testDevice2/MyROBlock *) + RO_real_a583_testDevice2 AT %MW296: REAL; + + (*AllTypes/testDevice2/MyROBlock *) + RO_dt_a583_testDevice2 AT %MW300: DT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_int8_a583_testDevice1 AT %MW308: ARRAY [0..1, 0..1] OF SINT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_uint8_a583_testDevice1 AT %MW312: ARRAY [0..1, 0..1] OF BYTE; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_int16_a583_testDevice1 AT %MW316: ARRAY [0..1, 0..1] OF INT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_uint16_a583_testDevice1 AT %MW324: ARRAY [0..1, 0..1] OF WORD; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_int32_a583_testDevice1 AT %MW332: ARRAY [0..1, 0..1] OF DINT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_uint32_a583_testDevice1 AT %MW348: ARRAY [0..1, 0..1] OF DWORD; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_float32_a583_testDevice1 AT %MW364: ARRAY [0..1, 0..1] OF REAL; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_string_a583_testDevice1 AT %MW380: ARRAY [0..1, 0..1] OF STRING(64); + + (*AllTypes/testDevice1/MyRWBlock *) + RW_date_a583_testDevice1 AT %MW640: ARRAY [0..1, 0..1] OF DT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_char_a583_testDevice1 AT %MW672: ARRAY [0..1, 0..1] OF SINT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_byte_a583_testDevice1 AT %MW676: ARRAY [0..1, 0..1] OF BYTE; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_word_a583_testDevice1 AT %MW680: ARRAY [0..1, 0..1] OF WORD; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_dword_a583_testDevice1 AT %MW688: ARRAY [0..1, 0..1] OF DWORD; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_int_a583_testDevice1 AT %MW704: ARRAY [0..1, 0..1] OF INT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_dint_a583_testDevice1 AT %MW712: ARRAY [0..1, 0..1] OF DINT; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_real_a583_testDevice1 AT %MW728: ARRAY [0..1, 0..1] OF REAL; + + (*AllTypes/testDevice1/MyRWBlock *) + RW_dt_a583_testDevice1 AT %MW744: ARRAY [0..1, 0..1] OF DT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_int8_a583_testDevice2 AT %MW776: ARRAY [0..1, 0..1] OF SINT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_uint8_a583_testDevice2 AT %MW780: ARRAY [0..1, 0..1] OF BYTE; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_int16_a583_testDevice2 AT %MW784: ARRAY [0..1, 0..1] OF INT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_uint16_a583_testDevice2 AT %MW792: ARRAY [0..1, 0..1] OF WORD; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_int32_a583_testDevice2 AT %MW800: ARRAY [0..1, 0..1] OF DINT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_uint32_a583_testDevice2 AT %MW816: ARRAY [0..1, 0..1] OF DWORD; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_float32_a583_testDevice2 AT %MW832: ARRAY [0..1, 0..1] OF REAL; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_string_a583_testDevice2 AT %MW848: ARRAY [0..1, 0..1] OF STRING(64); + + (*AllTypes/testDevice2/MyRWBlock *) + RW_date_a583_testDevice2 AT %MW1108: ARRAY [0..1, 0..1] OF DT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_char_a583_testDevice2 AT %MW1140: ARRAY [0..1, 0..1] OF SINT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_byte_a583_testDevice2 AT %MW1144: ARRAY [0..1, 0..1] OF BYTE; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_word_a583_testDevice2 AT %MW1148: ARRAY [0..1, 0..1] OF WORD; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_dword_a583_testDevice2 AT %MW1156: ARRAY [0..1, 0..1] OF DWORD; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_int_a583_testDevice2 AT %MW1172: ARRAY [0..1, 0..1] OF INT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_dint_a583_testDevice2 AT %MW1180: ARRAY [0..1, 0..1] OF DINT; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_real_a583_testDevice2 AT %MW1196: ARRAY [0..1, 0..1] OF REAL; + + (*AllTypes/testDevice2/MyRWBlock *) + RW_dt_a583_testDevice2 AT %MW1212: ARRAY [0..1, 0..1] OF DT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_int8_a583_testDevice1 AT %MW1244: ARRAY [0..9] OF SINT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_uint8_a583_testDevice1 AT %MW1254: ARRAY [0..9] OF BYTE; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_int16_a583_testDevice1 AT %MW1264: ARRAY [0..9] OF INT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_uint16_a583_testDevice1 AT %MW1284: ARRAY [0..9] OF WORD; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_int32_a583_testDevice1 AT %MW1304: ARRAY [0..9] OF DINT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_uint32_a583_testDevice1 AT %MW1344: ARRAY [0..9] OF DWORD; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_float32_a583_testDevice1 AT %MW1384: ARRAY [0..9] OF REAL; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_string_a583_testDevice1 AT %MW1424: ARRAY [0..9] OF STRING(64); + + (*AllTypes/testDevice1/MyWOBlock *) + WO_date_a583_testDevice1 AT %MW2076: ARRAY [0..9] OF DT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_char_a583_testDevice1 AT %MW2156: ARRAY [0..9] OF SINT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_byte_a583_testDevice1 AT %MW2166: ARRAY [0..9] OF BYTE; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_word_a583_testDevice1 AT %MW2176: ARRAY [0..9] OF WORD; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_dword_a583_testDevice1 AT %MW2196: ARRAY [0..9] OF DWORD; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_int_a583_testDevice1 AT %MW2236: ARRAY [0..9] OF INT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_dint_a583_testDevice1 AT %MW2256: ARRAY [0..9] OF DINT; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_real_a583_testDevice1 AT %MW2296: ARRAY [0..9] OF REAL; + + (*AllTypes/testDevice1/MyWOBlock *) + WO_dt_a583_testDevice1 AT %MW2336: ARRAY [0..9] OF DT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_int8_a583_testDevice2 AT %MW2416: ARRAY [0..9] OF SINT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_uint8_a583_testDevice2 AT %MW2426: ARRAY [0..9] OF BYTE; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_int16_a583_testDevice2 AT %MW2436: ARRAY [0..9] OF INT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_uint16_a583_testDevice2 AT %MW2456: ARRAY [0..9] OF WORD; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_int32_a583_testDevice2 AT %MW2476: ARRAY [0..9] OF DINT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_uint32_a583_testDevice2 AT %MW2516: ARRAY [0..9] OF DWORD; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_float32_a583_testDevice2 AT %MW2556: ARRAY [0..9] OF REAL; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_string_a583_testDevice2 AT %MW2596: ARRAY [0..9] OF STRING(64); + + (*AllTypes/testDevice2/MyWOBlock *) + WO_date_a583_testDevice2 AT %MW3248: ARRAY [0..9] OF DT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_char_a583_testDevice2 AT %MW3328: ARRAY [0..9] OF SINT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_byte_a583_testDevice2 AT %MW3338: ARRAY [0..9] OF BYTE; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_word_a583_testDevice2 AT %MW3348: ARRAY [0..9] OF WORD; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_dword_a583_testDevice2 AT %MW3368: ARRAY [0..9] OF DWORD; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_int_a583_testDevice2 AT %MW3408: ARRAY [0..9] OF INT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_dint_a583_testDevice2 AT %MW3428: ARRAY [0..9] OF DINT; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_real_a583_testDevice2 AT %MW3468: ARRAY [0..9] OF REAL; + + (*AllTypes/testDevice2/MyWOBlock *) + WO_dt_a583_testDevice2 AT %MW3508: ARRAY [0..9] OF DT; + +END_VAR \ No newline at end of file diff --git a/silecs-model/src/xml/DeploySchema.xsd b/silecs-model/src/xml/DeploySchema.xsd index cf53afb27cfcd7ae448f4fb2b0dddeb021f31ee5..073dadd560ee9f11733bab472b4ff5a8626062b7 100644 --- a/silecs-model/src/xml/DeploySchema.xsd +++ b/silecs-model/src/xml/DeploySchema.xsd @@ -278,7 +278,7 @@ </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="model" use="required" type="SiemensModelType"/> + <xs:attribute name="model" use="required" type="SiemensModelType" /> <xs:attribute name="protocol" type="BothProtocolType" use="required"> <xs:annotation> <xs:documentation>Data access mode is defined at PLC level for all @@ -336,7 +336,7 @@ </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="model" use="required" type="SchneiderModelType"/> + <xs:attribute name="model" use="required" type="SchneiderModelType" /> <xs:attribute name="protocol" type="BlockProtocolType" use="required"> <xs:annotation> <xs:documentation>Data access mode is defined at PLC level for all @@ -394,7 +394,7 @@ </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="model" use="required" type="BeckhoffModelType"/> + <xs:attribute name="model" use="required" type="BeckhoffModelType" /> <xs:attribute name="protocol" type="BlockProtocolType" use="required"> <xs:annotation> <xs:documentation>Data access mode is defined at PLC level for all @@ -452,7 +452,7 @@ </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="model" use="required" type="RabbitModelType"/> + <xs:attribute name="model" use="required" type="RabbitModelType" /> <xs:attribute name="protocol" type="BothProtocolType" use="required"> <xs:annotation> <xs:documentation>Data access mode is defined at PLC level for all @@ -502,7 +502,7 @@ </xs:appinfo> </xs:annotation> </xs:attribute> - <xs:attribute name="model" use="required" type="VirtualModelType"/> + <xs:attribute name="model" use="required" type="VirtualModelType" /> <xs:attribute name="protocol" type="BothProtocolType" use="required"> <xs:annotation> <xs:documentation>Data access mode is defined at PLC level for all the classes</xs:documentation> @@ -531,7 +531,7 @@ <xs:complexType name="NIControllerType"> <xs:complexContent> <xs:extension base="SimpleControllerType"> - <xs:attribute name="model" use="required" type="NIModelType"/> + <xs:attribute name="model" use="required" type="NIModelType" /> <xs:attribute name="system" type="NISystemType" use="required"> <xs:annotation> <xs:documentation>System infrastructure used to develop and/or @@ -563,8 +563,8 @@ </xs:extension> </xs:complexContent> </xs:complexType> - - <xs:simpleType name="HostNameType"> + + <xs:simpleType name="HostNameType"> <xs:restriction base="xs:string"> <xs:minLength value="1" /> <xs:pattern value="[_A-Za-z0-9]*" /> @@ -586,38 +586,6 @@ <xs:pattern value="[_A-Za-z][_A-Za-z0-9]*" /> </xs:restriction> </xs:simpleType> - - <xs:simpleType name="SiemensSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="STEP-7" /> - <xs:enumeration value="TIA-PORTAL" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="SchneiderSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="UNITY Pro" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="BeckhoffSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="TWINCat" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="RabbitSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="Standard-C" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="PCSystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="S7 virtual controller" /> - </xs:restriction> - </xs:simpleType> - <xs:simpleType name="NISystemType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="Labview" /> - </xs:restriction> - </xs:simpleType> <xs:simpleType name="BothProtocolType"> <xs:restriction base="xs:string"> <xs:enumeration value="DEVICE_MODE" /> @@ -652,6 +620,39 @@ <xs:enumeration value="TST" /> </xs:restriction> </xs:simpleType> + <xs:simpleType name="SiemensSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="STEP-7" /> + <xs:enumeration value="TIA-PORTAL" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="SchneiderSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="UNITY Pro" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="BeckhoffSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="TWINCat-2" /> + <xs:enumeration value="TWINCat-3" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="RabbitSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Standard-C" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="PCSystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="SNAP7 linux32" /> + <xs:enumeration value="SNAP7 linux64" /> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NISystemType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="Labview"/> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="SiemensModelType"> <xs:restriction base="xs:string"> <xs:enumeration value="SIMATIC_S7-300" />