diff --git a/silecs-codegen/src/xml/rabbitTemplate.py b/silecs-codegen/src/xml/DIGITemplate.py similarity index 52% rename from silecs-codegen/src/xml/rabbitTemplate.py rename to silecs-codegen/src/xml/DIGITemplate.py index b02681c958670691f6611ae13adc22f1f691f4b7..37dd2936144f79d1a029ebe4c66ba40463fd4a8c 100644 --- a/silecs-codegen/src/xml/rabbitTemplate.py +++ b/silecs-codegen/src/xml/DIGITemplate.py @@ -1,49 +1,42 @@ -#!/usr/bin/python -# Copyright 2016 CERN and GSI +# Project: SILECS +# Author: S.Magnoni/ BE-CO +# Date: August 2012 +# Last modification: Jannuary 2015 # -# 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. +# Description: +# This module implement the methods to build each components of the sources. +# A component source consists of one 'parameterizable' text that can +# be specialized on call to append the string to be stored in the file. # -# 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/>. import time -#========================================================================= -# Global definition -#========================================================================= -#------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Hash-Table -whichRabbitFormat = { - 'uint8' : 'uint16_t', - 'int8' : 'int16_t', - 'uint16' : 'uint16_t', - 'int16' : 'int16_t', - 'uint32' : 'uint32_t', - 'int32' : 'int32_t', - 'float32' : 'float', - 'uint64' : '8', - 'int64' : '8', +whichDIGIFormat = { + 'uint8' : 'uint16_t', + 'int8' : 'int16_t', + 'uint16' : 'uint16_t', + 'int16' : 'int16_t', + 'uint32' : 'uint32_t', + 'int32' : 'int32_t', + 'float32' : 'float', + 'uint64' : '8', + 'int64' : '8', 'string' : 'uint8_t', -# 'float64' : '8', not supported by microcontroller - 'date' : 'dt', - 'char' :'int16_t', - 'byte' :'uint16_t', - 'word' :'uint16_t', - 'dword' :'uint32_t', - 'int' :'int16_t', - 'dint' :'int32_t', - 'real' :'float', - 'dt' :'dt' } +# 'float64' : '8', not supported by microcontroller + 'date' : 'dt', + 'char' :'int16_t', + 'byte' :'uint16_t', + 'word' :'uint16_t', + 'dword' :'uint32_t', + 'int' :'int16_t', + 'dint' :'int32_t', + 'real' :'float', + 'dt' :'dt' +} #========================================================================= # Utils @@ -63,13 +56,13 @@ def toWordArray(strg): #========================================================================= header = """ -/* +------------------------------------------------------------------- - * | Copyright CERN 2015 - * | SILECS - BE/CO-SRC - * | April 2015 - * +------------------------------------------------------------------- - * - * Release : SILECS_%s +/* +------------------------------------------------------------------- + * | Copyright CERN 2015 + * | SILECS - BE/CO-SRC + * | April 2015 + * +------------------------------------------------------------------- + * + * Release : %s * * The following code has been automatically generated by SILECS. * @@ -77,27 +70,27 @@ header = """ * as int8_t, uint8_t, int16_t, etc.... * If your compiler does not support them natively please implement * them by including the data type definition provided on the SILECS - * web page before including this header file. + * web page before including this header file. */ #define MODBUS_START_ADDRESS %s -/*--------------------------------------------------------------------- +/*--------------------------------------------------------------------- * DT - * data type definition and related utilities + * data type definition and related utilities *--------------------------------------------------------------------- */ typedef struct { - uint8_t sc_100; // second cent - uint8_t sc; // second - uint8_t mn; // minute - uint8_t hh; // hour - uint8_t dd; // day - uint8_t mm; // month - uint8_t yy1; // year - uint8_t yy2; // year2 + uint8_t sc_100; // second cent + uint8_t sc; // second + uint8_t mn; // minute + uint8_t hh; // hour + uint8_t dd; // day + uint8_t mm; // month + uint8_t yy1; // year + uint8_t yy2; // year2 } dt; #define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F)) @@ -105,39 +98,39 @@ typedef struct void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date) { - date->sc_100 = sc_100; - date->sc = _tobcd(sc); - date->mn = _tobcd(mn); - date->hh = _tobcd(hh); - date->dd = _tobcd(dd); - date->mm = _tobcd(mm); - date->yy2 = _tobcd((int8_t)(yy/100)); - date->yy1 = _tobcd((int8_t)(yy%%100)); + date->sc_100 = sc_100; + date->sc = _tobcd(sc); + date->mn = _tobcd(mn); + date->hh = _tobcd(hh); + date->dd = _tobcd(dd); + date->mm = _tobcd(mm); + date->yy2 = _tobcd((int8_t)(yy/100)); + date->yy1 = _tobcd((int8_t)(yy%%100)); } -""" +""" #========================================================================= # DATA TYPE DEFINITION #========================================================================= firstBlockUDT = """ -/*--------------------------------------------------------------------- - * %s / v%s - * BLOCK Type definition +/*--------------------------------------------------------------------- + * %s / v%s + * BLOCK Type definition *--------------------------------------------------------------------- - */ + */ """ - -blockUDT = """ + +blockUDT = """ typedef struct -{ -%s -} _%s_%s; +{ +%s +} _%s_%s; """ regScalar = """ %s %s; -""" +""" regArray = """ %s %s[%s]; """ @@ -153,14 +146,11 @@ stringArray = """ %s %s[%s][%s][%s]; #========================================================================= allocationComment = """ -/*--------------------------------------------------------------------- +/*--------------------------------------------------------------------- * MEMORY ALLOCATION - * PROTOCOL: %s + * PROTOCOL: %s *--------------------------------------------------------------------- - */ -""" - -NBdeviceDefinition = """#define NB_%s_DEVICE %s + */ """ #======= DEVICE MODE ================= @@ -202,9 +192,6 @@ union silecsData { #======= BLOCK MODE ================= -blockModeDeviceInstantiation_deviceNumber = """ _%s_%s device[NB_%s_DEVICE]; -""" - blockModeDeviceInstantiation_deviceList = """ _%s_%s %s; """ @@ -237,40 +224,40 @@ globalAllocation = """ """ initFunctionDeviceMode = """ -/* Initialization function */ +/* Initialization function */ int SILECS_init() { - /* Silecs version initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "%s"); - - /* Silecs checksum initialization */ - silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = %s; - - /* Silecs user initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "%s"); - - /* Silecs date initialization */ - SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_device[0].hdrBlk._date); + /* Silecs version initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "%s"); + + /* Silecs checksum initialization */ + silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = %s; + + /* Silecs user initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "%s"); + + /* Silecs date initialization */ + SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_device[0].hdrBlk._date); } """ #initFunctionBlockMode = """ initFunctionBlockMode = """ -/* Initialization function */ +/* Initialization function */ int SILECS_init() { - /* Silecs version initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "%s"); - - /* Silecs checksum initialization */ - silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = %s; - - /* Silecs user initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "%s"); - - /* Silecs date initialization */ - SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date); + /* Silecs version initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "%s"); + + /* Silecs checksum initialization */ + silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = %s; + + /* Silecs user initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "%s"); + + /* Silecs date initialization */ + SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date); } """ @@ -290,13 +277,6 @@ deviceModeDeviceListExample = """ * silecsData.%s_%s.%s.%s = ....; */""" -deviceModeDeviceNumberExample = """ - * This example shows how to address the register %s of block %s - * of device 0 of the class %s - * - * silecsData.%s_device[0].%s.%s = ....; - */""" - blockModeDeviceListExample = """ * This example shows how to address the register %s of block %s * of device %s of the class %s @@ -304,44 +284,39 @@ blockModeDeviceListExample = """ * silecsData.%s_%s.%s.%s = ....; */""" -blockModeDeviceNumberExample = """ - * This example shows how to address the register %s of block %s - * of device 0 of the class %s - * - * silecsData.%s_%s.device[0].%s = ....; - */""" - #========================================================================= # C code generation Sub-function #========================================================================= # HEADER file ------------------------------------------------------------ -def cHeader(baseAddress,silecsVersion): - return header %(silecsVersion, baseAddress) +def cHeader(silecsRelease, baseAddress): + return header %(silecsRelease, baseAddress) # REGISTER definition ---------------------------------------------------- def cRegister(regName, regFormat, regDim, regDim2=1, strLen=1): - if strLen > 1: # if it's a string - if regDim2 > 1: # add another pair of brackets to hold the string length in case second dimension of array is set - return stringArray %(whichRabbitFormat[regFormat], regName, regDim, regDim2, strLen) - elif regDim > 1: # reuse the array2D syntax - return regArray2d %(whichRabbitFormat[regFormat], regName, regDim, strLen) - else: # regular string register - return regArray %(whichRabbitFormat[regFormat], regName, strLen) - else: - if regDim == 1 and regDim2 == 1: # scalar - return regScalar %(whichRabbitFormat[regFormat], regName) - elif regDim > 1 and regDim2 == 1: # array - return regArray %(whichRabbitFormat[regFormat], regName, regDim) - else: # dim1>=1 and for whatever dim2, use double array syntax - return regArray2d %(whichRabbitFormat[regFormat], regName, regDim, regDim2) + if strLen > 1: # if it's a string + if regDim2 > 1: # add another pair of brackets to hold the string length in case second dimension of array is set + return stringArray %(whichDIGIFormat[regFormat], regName, regDim, regDim2, strLen) + elif regDim > 1: # reuse the array2D syntax + return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, strLen) + else: # regular string register + return regArray %(whichDIGIFormat[regFormat], regName, strLen) + else: + if regDim == 1 and regDim2 == 1: # scalar + return regScalar %(whichDIGIFormat[regFormat], regName) + elif regDim > 1 and regDim2 == 1: # array + return regArray %(whichDIGIFormat[regFormat], regName, regDim) + else: # dim1>=1 and for whatever dim2, use double array syntax + return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, regDim2) + +def cFirstBlockUDT(className, classVersion): + return firstBlockUDT %(className, classVersion) + + # BLOCK type definition (UDT) -------------------------------------------- -def cBlockUDT(className, classVersion, blockName, regList, isFirst): - if isFirst: - return firstBlockUDT %(className, classVersion) + blockUDT %(regList, className, blockName) - else: - return blockUDT %(regList, className, blockName) +def cBlockUDT(className, blockName, regList): + return blockUDT %(regList, className, blockName) #============= DEVICE instantiation ============= @@ -349,10 +324,8 @@ def cBlockUDT(className, classVersion, blockName, regList, isFirst): # GLOBAL instantiation ---------------------------------------------- def cAllocationComment(plcProtocol): - return allocationComment %(plcProtocol) + return allocationComment %(plcProtocol) -def cNBdeviceDefinition(className,deviceNumber): - return NBdeviceDefinition %(className,deviceNumber) # DEVICE MODE instantiation ---------------------------------------------- @@ -370,9 +343,6 @@ def cDeviceModeDataInstantiation(classList): # BLOCK MODE instantiation ---------------------------------------------- -def cBlockModeDeviceInstantiation_deviceNumber(className, blockName): - return blockModeDeviceInstantiation_deviceNumber %(className, blockName, className) - def cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceName): return blockModeDeviceInstantiation_deviceList %(className, blockName, deviceName) @@ -380,31 +350,20 @@ def cBlockModeBlockInstantiation(deviceList, className, blockName): return blockModeBlockInstantiation %(deviceList, className, blockName) def cBlockModeDataInstantiation(classList): - return blockMode_dataInstantiation %(classList) + return blockMode_dataInstantiation %(classList) # Init Function ---------------------------------------------- -def cInitDeviceMode(silecsVersion,ieChecks,ieUser): +def cInitDeviceMode(ieVersion,ieChecks,ieUser): dt = time.localtime(time.time()) - return initFunctionDeviceMode %("SILECS_"+silecsVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0]) + return initFunctionDeviceMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0]) -def cInitBlockMode(silecsVersion,ieChecks,ieUser): +def cInitBlockMode(ieVersion,ieChecks,ieUser): dt = time.localtime(time.time()) - return initFunctionBlockMode %("SILECS_"+silecsVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0]) + return initFunctionBlockMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0]) # Example function ---------------------------------------------- -def cExample(plcProtocol,withDeviceList,className, blockName, registerName, deviceLabel =''): - - if plcProtocol == 'DEVICE_MODE': - if withDeviceList == True: - # device mode - device list - return instantiationExample + deviceModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, deviceLabel, blockName, registerName) - else: - # device mode - device number - return instantiationExample + deviceModeDeviceNumberExample %(registerName, blockName, className, className, blockName, registerName) +def cExample(plcProtocol,className, blockName, registerName, deviceLabel =''): + if plcProtocol == 'DEVICE_MODE': + return instantiationExample + deviceModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, deviceLabel, blockName, registerName) else: - if withDeviceList == True: - # block mode - device list - return instantiationExample + blockModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, blockName, deviceLabel, registerName) - else: - # block mode - device number - return instantiationExample + blockModeDeviceNumberExample %(registerName, blockName, className, className, blockName, registerName) + return instantiationExample + blockModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, blockName, deviceLabel, registerName) diff --git a/silecs-codegen/src/xml/genplcsrc.py b/silecs-codegen/src/xml/genplcsrc.py index a259f4fe26cdb2f983eb4c35072aaca956b5ff21..30bc66eb921fd24d267406dde65f7cd76a609900 100644 --- a/silecs-codegen/src/xml/genplcsrc.py +++ b/silecs-codegen/src/xml/genplcsrc.py @@ -24,9 +24,11 @@ import iefiles import xmltemplate import s7template import virtualS7Template -import rabbitTemplate +import DIGITemplate from iecommon import * +from model.Param.Param import * +from model.Param.Controller import * from model.Class.Register import ParamRegister from model.Class.Block import ParamBlock from model.Class.Class import ParamClass @@ -40,17 +42,6 @@ from model.Deploy.Deploy import * #This Python-script generates PLC sources document from XML Parameter documents #which are supposed to be well-formed (generated with the 'genparam' script). - -# Deploy global information -class DeploymentInfo(object): - plcModel = None # S7-300, .., Premium, .. - plcSystem = None # UNITY, STEP-7, TIA-PORTAL, ... - plcProtocol = None # DEVICE_MODE or BLOCK_MODE - address = None - checksum = None # checksum of the related parameter file - owner = None # onwer of the Deployment document - silecsVersion = None - whichUnityFormat = { 'uint8' : 'BYTE', 'int8' : 'WORD', @@ -139,21 +130,17 @@ def getDateTime(): #------------------------------------------------------------------------- # SIEMENS PLC code generation #------------------------------------------------------------------------- -def generateSiemensSources(paramDOM, sourceFolderPath ,logTopics): +def generateSiemensSources(param, sourceFolderPath ,logTopics): stlString = '' symString = '' # for .sdf Symbol file - deploy = getDeploymentInformation(paramDOM) - # Prepare the Simatic Symbols (<.sdf> file) - DBnumber = long(deploy.address) #first data-block (SilecsHeader) starts from the base-address - UDTnumber = long(deploy.address) #use base data-block address for UDT number as well (to be reserved by the developer) + 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) # Generate sources for each class that is deployed in the PLC - for paramClass in ParamClass.getParamClassesFromRootNode(paramDOM): + for paramClass in param.controller.paramClasses: deviceDOMList = paramClass.getDeviceInstanceNodes() # get Device instances of that class - deviceNumber = len(deviceDOMList) - # Generate the Blocks definition for blockIndex, block in enumerate(paramClass.getParamBlocks()): registerList = '' @@ -165,25 +152,25 @@ def generateSiemensSources(paramDOM, sourceFolderPath ,logTopics): , True,logTopics) #create register value if required (diagnostic registers assignment in particular) - registerValue = s7template.stlRegisterValue(register.name, deploy.owner, getDateTime(), deploy.checksum,deploy.silecsVersion) + registerValue = s7template.stlRegisterValue(register.name, param.owner, getDateTime(), param.checksum,param.silecsVersion) if register.format == 'string': registerList += s7template.stlRegister(register.name, register.format, register.dim1, register.dim2, registerValue, long(register.stringLength)) else: registerList += s7template.stlRegister(register.name, register.format, register.dim1, register.dim2, registerValue) - stlString += s7template.stlBlockUDT(deploy.owner, paramClass.name, paramClass.version, block.name, registerList, (blockIndex == 0)) + stlString += s7template.stlBlockUDT(param.owner, paramClass.name, paramClass.version, block.name, registerList, (blockIndex == 0)) symString += s7template.symBlockUDT(paramClass.name, paramClass.version, block.name, UDTnumber, (blockIndex == 0)) UDTnumber += 1 - if deploy.plcProtocol == 'DEVICE_MODE': + if param.controller.protocol == 'DEVICE_MODE': # Generate the Data-Blocks: one DB per Device instance for deviceIndex, deviceDOM in enumerate(deviceDOMList): blockList = '' for block in paramClass.getParamBlocks(): blockList += s7template.stlBlock(paramClass.name, block.name) deviceLabel = deviceDOM.prop('label') - stlString += s7template.generateBlock(deploy.owner, paramClass.name, paramClass.version, deploy.plcSystem, DBnumber, deviceLabel, blockList, (deviceIndex == 0),deploy.plcProtocol) + stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, deviceLabel, blockList, (deviceIndex == 0),param.controller.protocol) symString += s7template.symDeviceDB(paramClass.name, paramClass.version, deviceLabel, DBnumber, (deviceIndex == 0)) DBnumber += 1 @@ -195,22 +182,22 @@ def generateSiemensSources(paramDOM, sourceFolderPath ,logTopics): deviceLabel = deviceDOM.prop('label') deviceList += s7template.stlDevice(deviceLabel, paramClass.name, block.name) - stlString += s7template.generateBlock(deploy.owner, paramClass.name, paramClass.version, deploy.plcSystem, DBnumber, block.name, deviceList, (blockIndex == 0),deploy.plcProtocol) + stlString += s7template.generateBlock(param.owner, paramClass.name, paramClass.version, param.controller.system, DBnumber, block.name, deviceList, (blockIndex == 0),param.controller.protocol) symString += s7template.symBlockDB(paramClass.name, paramClass.version, block.name, DBnumber, (blockIndex == 0)) DBnumber += 1 # write the String PLC generated code - generateControllerFiles(sourceFolderPath,deploy,".scl",stlString,logTopics); + generateControllerFiles(sourceFolderPath,param.controller.hostName,".scl",stlString,logTopics); # Write the String PLC generated symbols into the <.sdf> symbols file - generateControllerFiles(sourceFolderPath,deploy,".sdf",symString,logTopics); + generateControllerFiles(sourceFolderPath,param.controller.hostName,".sdf",symString,logTopics); #------------------------------------------------------------------------- # SCHNEIDER PLC code generation #------------------------------------------------------------------------- # ---------------------------------------------------- -def generateSchneiderRegisters(xsydoc, paramClass, deviceDOM, block, deviceIndex, modeDevice, deploy, logTopics): +def generateSchneiderRegisters(xsydoc, paramClass, deviceDOM, block, deviceIndex, modeDevice, param, logTopics): deviceLabel = deviceDOM.prop('label') @@ -250,9 +237,9 @@ def generateSchneiderRegisters(xsydoc, paramClass, deviceDOM, block, deviceIndex regElt.setProp("topologicalAddress", "%%MW%ld" %totalAddress) if block.name == 'hdrBlk': initElt = libxml2.newNode('variableInit') - if register.name == '_version': initElt.setProp("value", deploy.silecsVersion ) - if register.name == '_user' : initElt.setProp("value", deploy.owner) - if register.name == '_checksum': initElt.setProp("value", "%s" %deploy.checksum) + if register.name == '_version': initElt.setProp("value", param.silecsVersion ) + if register.name == '_user' : initElt.setProp("value", param.owner) + if register.name == '_checksum': initElt.setProp("value", "%s" %param.checksum) if register.name == '_date' : initElt.setProp("value", getDateTime()) regElt.addChild(initElt) commElt = libxml2.newNode('comment') @@ -261,12 +248,10 @@ def generateSchneiderRegisters(xsydoc, paramClass, deviceDOM, block, deviceIndex dataElt.addChild(regElt) # ---------------------------------------------------- -def generateSchneiderSources(paramDOM,sourceFolderPath,logTopics): +def generateSchneiderSources(param,sourceFolderPath,logTopics): #Base address provided by the user in the Deployment relies on the PLC model: #Quantum, Premium and M340 Schneider PLCs are all interpreted as using 16-bit addressing, #even though M340 addresses are later properly considered as 32-bit addresses - - deploy = getDeploymentInformation(paramDOM) # Create the Schneider DOM source (Unity <.XSY> XML document) xsyDoc = libxml2.newDoc(version='1.0') @@ -275,200 +260,78 @@ def generateSchneiderSources(paramDOM,sourceFolderPath,logTopics): dataElt = libxml2.newNode('dataBlock') rootElt.addChild(dataElt) - for paramClass in ParamClass.getParamClassesFromRootNode(paramDOM): + for paramClass in param.controller.paramClasses: deviceDOMList = paramClass.getDeviceInstanceNodes() # get Device instances of that class for block in paramClass.getParamBlocks(): for deviceIndex,deviceDOM in enumerate(deviceDOMList): - if deploy.plcProtocol == 'DEVICE_MODE': #------------------- - generateSchneiderRegisters(xsyDoc, paramClass, deviceDOM, block, deviceIndex, True, deploy, logTopics) + if param.controller.protocol == 'DEVICE_MODE': #------------------- + generateSchneiderRegisters(xsyDoc, paramClass, deviceDOM, block, deviceIndex, True, param, logTopics) else: - generateSchneiderRegisters(xsyDoc, paramClass, deviceDOM, block, deviceIndex, False, deploy, logTopics) + generateSchneiderRegisters(xsyDoc, paramClass, deviceDOM, block, deviceIndex, False, param, logTopics) # Finally, write the DOM object (PLC generated code) into the XSY source file - generateControllerFiles(sourceFolderPath,deploy,".xsy",rootElt.serialize(format = True),logTopics); + generateControllerFiles(sourceFolderPath,param.controller.hostName,".xsy",rootElt.serialize(format = True),logTopics); xsyDoc.freeDoc() # ---------------------------------------------------- -def generateRabbitSources(paramDOM,sourceFolderPath,logTopics): +def generateDIGISources(param,sourceFolderPath,logTopics): deviceLabel = '' - - deploy = getDeploymentInformation(paramDOM) - - # Prepare the source (<.h> file) with its diagnostic data-block header - cCodeString = rabbitTemplate.cHeader(deploy.address,deploy.silecsVersion) + cCodeString = DIGITemplate.cHeader(param.silecsVersion, param.controller.address) cTypeDefinitions = '' - cDataAllocation = rabbitTemplate.cAllocationComment(deploy.plcProtocol) + cDataAllocation = DIGITemplate.cAllocationComment(param.controller.protocol) blockList = '' classList = '' NBdeviceDefinitionList = '' - for paramClass in ParamClass.getParamClassesFromRootNode(paramDOM): - deviceDOMList = paramClass.getDeviceInstanceNodes() # get Device instances of that class - deviceNumber = len(deviceDOMList) - - #==== Generate the Blocks definition ==== - for blockIndex, block in enumerate(paramClass.getParamBlocks()): + for paramClass in param.controller.paramClasses: + cTypeDefinitions += DIGITemplate.cFirstBlockUDT(paramClass.name, paramClass.version) + for block in paramClass.getParamBlocks(): registerList = '' for register in block.getParamRegisters(): - # If PLC does not supports this register format abort this generation and log the error - if(register.format in ['float64']): - iecommon.logError('ERROR: In register '+ register.name +', '+register.format+' format not supported for current controller model.', True,logTopics) - - if(register.format == 'string'): - registerList += rabbitTemplate.cRegister(register.name, register.format, register.dim1, register.dim2, long(register.stringLength)) + if register.format == 'float64': + iecommon.logError('ERROR: In register '+register.name+', '+ register.format +' format not supported for current controller model.', True,logTopics) + if register.format == 'string': + registerList += DIGITemplate.cRegister(register.name, register.format, register.dim1, register.dim2, register.stringLength) else: - registerList += rabbitTemplate.cRegister(register.name, register.format, register.dim1, register.dim2) + registerList += DIGITemplate.cRegister(register.name, register.format, register.dim1, register.dim2) - cTypeDefinitions += rabbitTemplate.cBlockUDT(paramClass.name, paramClass.version, block.name, registerList, (blockIndex == 0)) + cTypeDefinitions += DIGITemplate.cBlockUDT(paramClass.name, block.name, registerList) #==== Memory allocation ==== - if deploy.plcProtocol == 'DEVICE_MODE': + if param.controller.protocol == 'DEVICE_MODE': # Generate the List of block in the class blockList ='' for block in paramClass.getParamBlocks(): - blockList += rabbitTemplate.cDeviceModeBlockInstantiation(paramClass.name, block.name) + blockList += DIGITemplate.cDeviceModeBlockInstantiation(paramClass.name, block.name) deviceList = '' - for deviceDOM in deviceDOMList: + for deviceDOM in paramClass.getDeviceInstanceNodes(): deviceLabel = paramClass.name + "_" + deviceDOM.prop('label') deviceList += deviceLabel + ', '; deviceList = deviceList[:-2] # remove last comma space - classList += rabbitTemplate.cDeviceModeClass_deviceList(blockList, deviceList) - - + classList += DIGITemplate.cDeviceModeClass_deviceList(blockList, deviceList) else: # BLOCK_MODE - # Generate the List of block in the class for block in paramClass.getParamBlocks(): + # DeviceList deviceList = '' - for deviceDOM in deviceDOMList: + for deviceDOM in paramClass.getDeviceInstanceNodes(): deviceLabel = deviceDOM.prop('label') - deviceList +=rabbitTemplate.cBlockModeDeviceInstantiation_deviceList(paramClass.name, block.name, deviceLabel) - - blockList += rabbitTemplate.cBlockModeBlockInstantiation(deviceList, paramClass.name, block.name) - - # Predefine number of devices constant - cDataAllocation += NBdeviceDefinitionList - - if deploy.plcProtocol == 'DEVICE_MODE': - cDataAllocation += rabbitTemplate.cDeviceModeDataInstantiation(classList) - cInitFunction = rabbitTemplate.cInitDeviceMode(deploy.silecsVersion,deploy.checksum,deploy.owner) - else: - cDataAllocation += rabbitTemplate.cBlockModeDataInstantiation(blockList) - cInitFunction = rabbitTemplate.cInitBlockMode(deploy.silecsVersion,deploy.checksum,deploy.owner) - - - # Append data definitions - cCodeString += cTypeDefinitions - - # Append data allocation - cCodeString += cDataAllocation - - # Append initialization function - cCodeString += cInitFunction - - # Generate and append sample example - cCodeString += rabbitTemplate.cExample(deploy.plcProtocol,True,paramClass.name, block.name, register.name, deviceLabel) - - # Finally, write the String C generated code into the temporal output file - generateControllerFiles(sourceFolderPath,deploy,".h",cCodeString,logTopics); - - -# ---------------------------------------------------- -def generatePCLikeSources(paramDOM,sourceFolderPath,logTopics): - deviceLabel = '' - - deploy = getDeploymentInformation(paramDOM) - - # Prepare the source (<.h> file) with its diagnostic data-block header - cCodeString = PCLikeTemplate.cHeader(deploy.baseAddress) - cTypeDefinitions = '' - cDataAllocation = PCLikeTemplate.cAllocationComment(deploy.plcProtocol) - - blockList = '' - classList = '' - NBdeviceDefinitionList = '' - - # Generate sources for each class that is deployed in the PLC - for paramClass in ParamClass.getParamClassesFromRootNode(paramDOM): - - deviceNumber = len(deviceDOMList) - - #==== Generate the Blocks definition ==== - for blockIndex, blockDOM in enumerate(blockDOMList): - registerList = '' - blockName = blockDOM.getAttribute('name') - registerDOMList = blockDOM.getElementsByTagName("Register") # get Registers of the current block - for registerIndex, registerDOM in enumerate(registerDOMList): - registerName = registerDOM.getAttribute('name') - registerFormat = registerDOM.getAttribute('format') - registerDimension1 = long(registerDOM.getAttribute('array-dim1')) - registerDimension2 = long(registerDOM.getAttribute('array-dim2')) - - # If PLC does not supports this register format abort this generation and log the error - if(registerFormat in ['float64']): - iecommon.logError('ERROR: In register '+registerName+', '+registerFormat+' format not supported for current controller model.', True,logTopics) - - if(registerFormat == 'string'): - registerList += PCLikeTemplate.cRegister(registerName, registerFormat, registerDimension1, registerDimension2, long(registerDOM.getAttribute('string-len'))) - else: - registerList += PCLikeTemplate.cRegister(registerName, registerFormat, registerDimension1, registerDimension2) - - cTypeDefinitions += PCLikeTemplate.cBlockUDT(className, classVersion, blockName, registerList, (blockIndex == 0)) - - #==== Memory allocation ==== - if deploy.plcProtocol == 'DEVICE_MODE': - # Generate the List of block in the class - blockList ='' - for blockIndex, blockDOM in enumerate(blockDOMList): - blockName = blockDOM.getAttribute('name') - blockList += PCLikeTemplate.cDeviceModeBlockInstantiation(className, blockName) - # instantiate for deviceList / deviceNumber - if withDeviceList == True: - # DeviceList - deviceList = '' - for deviceDOM in deviceDOMList: - deviceLabel = className + "_" + deviceDOM.getAttribute('label') - deviceList += deviceLabel + ', '; - deviceList = deviceList[:-2] # remove last comma space - classList += PCLikeTemplate.cDeviceModeClass_deviceList(blockList, deviceList) - else : - # DeviceNumber - classList += PCLikeTemplate.cDeviceModeClass_deviceNumber(className, blockList) - NBdeviceDefinitionList += PCLikeTemplate.cNBdeviceDefinition(className,deviceNumber) - - else: # BLOCK_MODE - # Generate the List of block in the class - for blockIndex, blockDOM in enumerate(blockDOMList): - # create instantation for current block - blockName = blockDOM.getAttribute('name') - if withDeviceList == True: - # DeviceList - deviceList = '' - for deviceDOM in deviceDOMList: - deviceLabel = deviceDOM.getAttribute('label') - deviceList +=PCLikeTemplate.cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceLabel) - else: - # DeviceNumber - deviceList = PCLikeTemplate.cBlockModeDeviceInstantiation_deviceNumber(className, blockName) - + deviceList +=DIGITemplate.cBlockModeDeviceInstantiation_deviceList(paramClass.name, block.name, deviceLabel) # allocation is the same with device list or device number - blockList += PCLikeTemplate.cBlockModeBlockInstantiation(deviceList, className, blockName) - - if withDeviceList == False: - NBdeviceDefinitionList += PCLikeTemplate.cNBdeviceDefinition(className,deviceNumber) + blockList += DIGITemplate.cBlockModeBlockInstantiation(deviceList, paramClass.name, block.name) # Predefine number of devices constant cDataAllocation += NBdeviceDefinitionList - if deploy.plcProtocol == 'DEVICE_MODE': - cDataAllocation += PCLikeTemplate.cDeviceModeDataInstantiation(classList) - cInitFunction = PCLikeTemplate.cInitDeviceMode(ieglobal.version,deploy.checksumRef,deploy.owner) + if param.controller.protocol == 'DEVICE_MODE': + cDataAllocation += DIGITemplate.cDeviceModeDataInstantiation(classList) + cInitFunction = DIGITemplate.cInitDeviceMode(param.silecsVersion,param.checksum,param.owner) else: - cDataAllocation += PCLikeTemplate.cBlockModeDataInstantiation(blockList) - cInitFunction = PCLikeTemplate.cInitBlockMode(ieglobal.version,deploy.checksumRef,deploy.owner) + cDataAllocation += DIGITemplate.cBlockModeDataInstantiation(blockList) + cInitFunction = DIGITemplate.cInitBlockMode(param.silecsVersion,param.checksum,param.owner) # Append data definitions @@ -481,34 +344,24 @@ def generatePCLikeSources(paramDOM,sourceFolderPath,logTopics): cCodeString += cInitFunction # Generate and append sample example - cCodeString += PCLikeTemplate.cExample(deploy.plcProtocol,withDeviceList,className, blockName, registerName, deviceLabel) + cCodeString += DIGITemplate.cExample(param.controller.protocol,paramClass.name, block.name, register.name, deviceLabel) # Finally, write the String C generated code into the temporal output file - sourcesPath = iefiles.getControllerSourcesDirectory(workspacePath, deploy.plcName, deploy.deployVersion) - sourcesFile = os.path.normpath(sourcesPath + "/%s.h" % deploy.plcName) - iecommon.logInfo("Generate PLC sources: %s" %sourcesFile,logTopics); - fdesc = open(sourcesFile, "w") - fdesc.write(cCodeString) - fdesc.close() - - # Clean-up the memory before return - deployDOM.unlink() + generateControllerFiles(sourceFolderPath,param.controller.hostName,".h",cCodeString,logTopics); # ---------------------------------------------------- -def generateVirtualS7Sources(deployDOM, classDOCList, deploy, workspacePath,logTopics): - +def generateVirtualS7Sources(param,sourceFolderPath,logTopics): includeDesign = '' allocDesign = '' deleteDesign = '' getDesign = '' protocolMode = 'BlockMode'; - if deploy.plcProtocol == 'DEVICE_MODE': + if param.controller.protocol == 'DEVICE_MODE': protocolMode = 'DeviceMode'; - duConstructor = virtualS7Template.vs7DuConstructor(deploy.plcName, deploy.deployVersion, protocolMode, deploy.baseAddress) + duConstructor = virtualS7Template.vs7DuConstructor(param.deployName, param.deployVersion, protocolMode, param.controller.address) - # Generate sources for each class that is deployed in the PLC - for classDOC in classDOCList: + for paramClass in param.controller.paramClasses: blocksCodeString = '' createBlockCodeString = '' @@ -518,21 +371,15 @@ def generateVirtualS7Sources(deployDOM, classDOCList, deploy, workspacePath,logT createDeviceCodeString = '' deleteDeviceCodeString = '' designCodeString = '' - - classDOM = classDOC.getElementsByTagName("SILECS-Class")[0] #only one SILECS-Class node is expected - blockDOMList = classDOC.getElementsByTagName("Block") # get Blocks elements of that class - - className = classDOM.getAttribute('name') - classVersion = classDOM.getAttribute('version') - + #DEPLOY-UNIT code generation ============================ - includeDesign += virtualS7Template.vs7DuDesignInclude(className, classVersion) - allocDesign += virtualS7Template.vs7DuDesignAlloc(className, classVersion) - deleteDesign += virtualS7Template.vs7DuDesignDelete(className) - getDesign += virtualS7Template.vs7DuDesignGet(className, classVersion) + includeDesign += virtualS7Template.vs7DuDesignInclude(paramClass.name, paramClass.version) + allocDesign += virtualS7Template.vs7DuDesignAlloc(paramClass.name, paramClass.version) + deleteDesign += virtualS7Template.vs7DuDesignDelete(paramClass.name) + getDesign += virtualS7Template.vs7DuDesignGet(paramClass.name, paramClass.version) #CLASSES code generation ================================ - for blockIndex, blockDOM in enumerate(blockDOMList): + for block in paramClass.getParamBlocks(): getSetCodeString = '' dimsCodeString = '' dataCodeString = '' @@ -540,87 +387,66 @@ def generateVirtualS7Sources(deployDOM, classDOCList, deploy, workspacePath,logT currentRegisterAddress = 0 #used to compute even/odd adress and insert align data by adding dummy registers previousRegisterMemSize = 0 #... dummyIndex = 0; - - blockName = blockDOM.getAttribute('name') - blockOffset = blockDOM.getAttribute('address') - registerDOMList = blockDOM.getElementsByTagName("Register") # get Registers of the current block - - createBlockCodeString += virtualS7Template.vs7ClassCreateBlock(className, blockName) - deleteBlockCodeString += virtualS7Template.vs7ClassDeleteBlock(className, blockName) - - for registerIndex, registerDOM in enumerate(registerDOMList): - registerName = registerDOM.getAttribute('name') - registerFormat = registerDOM.getAttribute('format') - registerDimension1 = long(registerDOM.getAttribute('array-dim1')) - registerDimension2 = long(registerDOM.getAttribute('array-dim2')) - registerMemSize = long(registerDOM.getAttribute('mem-size')) #store the reigster mem-size for next iteration - - registerLength = 1 #in case string - if(registerFormat == 'string'): - registerLength = long(registerDOM.getAttribute('string-len')) + + createBlockCodeString += virtualS7Template.vs7ClassCreateBlock(paramClass.name, block.name) + deleteBlockCodeString += virtualS7Template.vs7ClassDeleteBlock(paramClass.name, block.name) - getSetCodeString += virtualS7Template.vs7ClassGetSet(registerName, registerFormat, registerDimension1, registerDimension2,registerLength) - dimsCodeString += virtualS7Template.vs7ClassDimension(registerName, registerFormat, registerDimension1, registerDimension2,registerLength) + for register in block.getParamRegisters(): + getSetCodeString += virtualS7Template.vs7ClassGetSet(register.name, register.format, register.dim1, register.dim2,register.stringLength) + dimsCodeString += virtualS7Template.vs7ClassDimension(register.name, register.format, register.dim1, register.dim2,register.stringLength) #Specific code to force 16bit alignment if not scalar 8bit register (==> insert dummy register if needed) - dummyCodeString = virtualS7Template.vs7ClassDummyRegister(currentRegisterAddress, previousRegisterMemSize, registerMemSize, dummyIndex) + dummyCodeString = virtualS7Template.vs7ClassDummyRegister(currentRegisterAddress, previousRegisterMemSize, register.memSize, dummyIndex) dataCodeString += dummyCodeString - currentRegisterAddress += registerMemSize + currentRegisterAddress += register.memSize if dummyCodeString != "": dummyIndex += 1 currentRegisterAddress += 1 #and now insert the normal data register - dataCodeString += virtualS7Template.vs7ClassDataRegister(registerName, registerFormat, registerDimension1, registerDimension2, registerLength) - previousRegisterMemSize = registerMemSize + dataCodeString += virtualS7Template.vs7ClassDataRegister(register.name, register.format, register.dim1, register.dim2, register.stringLength) + previousRegisterMemSize = register.memSize - blocksCodeString += virtualS7Template.vs7ClassBlock(ieglobal.version, deploy.owner, deploy.checksumRef, className, blockName, getSetCodeString, blockOffset, dimsCodeString, dataCodeString) + blocksCodeString += virtualS7Template.vs7ClassBlock(param.silecsVersion, param.owner, param.checksum, paramClass.name, block.name, getSetCodeString, block.address, dimsCodeString, dataCodeString) - deviceDOMList = classDOC.getElementsByTagName("Instance") # get Device instances of that class - for deviceIndex, deviceDOM in enumerate(deviceDOMList): - deviceLabel = deviceDOM.getAttribute('label') - createDeviceCodeString += virtualS7Template.vs7ClassCreateDevice(className, deviceLabel, deviceIndex) - deleteDeviceCodeString += virtualS7Template.vs7ClassDeleteDevice(className, deviceLabel) + for deviceIndex, deviceDOM in enumerate(paramClass.getDeviceInstanceNodes()): + deviceLabel = deviceDOM.prop('label') + createDeviceCodeString += virtualS7Template.vs7ClassCreateDevice(paramClass.name, deviceLabel, deviceIndex) + deleteDeviceCodeString += virtualS7Template.vs7ClassDeleteDevice(paramClass.name, deviceLabel) deviceCodeString = virtualS7Template.vs7ClassDevice(createBlockCodeString, deleteBlockCodeString) - designCodeString = virtualS7Template.vs7ClassDesign(className, classVersion, createDeviceCodeString, deleteDeviceCodeString) + designCodeString = virtualS7Template.vs7ClassDesign(paramClass.name, paramClass.version, createDeviceCodeString, deleteDeviceCodeString) - classCodeString = virtualS7Template.vs7ClassHeader(className, classVersion, blocksCodeString, deviceCodeString, designCodeString) + classCodeString = virtualS7Template.vs7ClassHeader(paramClass.name, paramClass.version, blocksCodeString, deviceCodeString, designCodeString) # Finally, write the CLASS generated code into the temporal output file - sourcesPath = iefiles.getControllerSourcesDirectory(workspacePath, deploy.plcName, deploy.deployVersion) - sourcesFile = os.path.normpath(sourcesPath + "/%s_%s.h" % (className, classVersion)) + sourcesFile = os.path.normpath(sourceFolderPath + "/%s_%s.h" % (paramClass.name, paramClass.version)) iecommon.logInfo("Generate PLC sources: %s" %sourcesFile,logTopics); fdesc = open(sourcesFile, "w") fdesc.write(classCodeString) fdesc.close() # Prepare the source (<.h> file) with its diagnostic data-block header - duCodeString = virtualS7Template.vs7DuHeader(deploy.plcName, deploy.deployVersion, duConstructor, includeDesign, allocDesign, deleteDesign, getDesign) + duCodeString = virtualS7Template.vs7DuHeader(param.controller.hostName, param.deployVersion, duConstructor, includeDesign, allocDesign, deleteDesign, getDesign) # Write the DEPLOY-UNIT generated code into the temporal output file - sourcesPath = iefiles.getControllerSourcesDirectory(workspacePath, deploy.plcName, deploy.deployVersion) - sourcesFile = os.path.normpath(sourcesPath + "/%s_%s.h" % (deploy.plcName, deploy.deployVersion)) + sourcesFile = os.path.normpath(sourceFolderPath + "/%s_%s.h" % (param.deployName, param.deployVersion)) iecommon.logInfo("Generate PLC sources: %s" %sourcesFile,logTopics); fdesc = open(sourcesFile, "w") fdesc.write(duCodeString) fdesc.close() # Prepare the source (<.h> file) with its diagnostic data-block header - mainCodeString = virtualS7Template.vs7MainCode(deploy.plcName, deploy.deployVersion) + mainCodeString = virtualS7Template.vs7MainCode(param.deployName, param.deployVersion) # Finally, write the DEPLOY-UNIT generated code into the temporal output file - sourcesPath = iefiles.getControllerSourcesDirectory(workspacePath, deploy.plcName, deploy.deployVersion) - sourcesFile = os.path.normpath(sourcesPath + "/%s_%s.cpp" % (deploy.plcName, deploy.deployVersion)) + sourcesFile = os.path.normpath(sourceFolderPath + "/%s_%s.cpp" % (param.controller.hostName, param.deployVersion)) iecommon.logInfo("Generate PLC sources: %s" %sourcesFile,logTopics); fdesc = open(sourcesFile, "w") fdesc.write(mainCodeString) fdesc.close() - # Clean-up the memory before return - deployDOM.unlink() - # ---------------------------------------------------- -def generateBeckhoffRegisters(paramClass, deviceDOM, block, deviceIndex, deploy, logTopics): +def generateBeckhoffRegisters(param, paramClass, deviceDOM, block, deviceIndex, logTopics): source = '' deviceLabel = deviceDOM.prop('label') @@ -639,12 +465,12 @@ def generateBeckhoffRegisters(paramClass, deviceDOM, block, deviceIndex, deploy, # 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 deploy.plcModel == 'BC9020': - totalAddress = (block.address - long(deploy.address) + (deviceIndex * block.memSize) + register.address)/2 - elif deploy.plcModel == 'CX9020': - totalAddress = (block.address - long(deploy.address) + (deviceIndex * block.memSize) + register.address) + if param.controller.model == 'BC9020': + totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address)/2 + elif param.controller.model == 'CX9020': + totalAddress = (block.address - long(param.controller.address) + (deviceIndex * block.memSize) + register.address) else: - raise "PLC model not supported: " + deploy.plcModel + raise "PLC model not supported: " + param.controller.model # add comment to source to identify block source += ' (*'+paramClass.name+'/'+deviceLabel+'/'+block.name+' *)\r\n' @@ -654,11 +480,11 @@ def generateBeckhoffRegisters(paramClass, deviceDOM, block, deviceIndex, deploy, if block.name == 'hdrBlk': if register.name == '_version': - source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format]+"(16)", deploy.silecsVersion ) + source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format]+"(16)", param.silecsVersion ) if register.name == '_user': - source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format]+"(16)", "'"+deploy.owner+"'") + source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format]+"(16)", "'"+param.owner+"'") if register.name == '_checksum': - source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format], deploy.checksum) + source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format], param.checksum) if register.name == '_date': source+=beckhoffRegInit %(register.name, classNameCRC, deviceLabel, totalAddress, whichTwincatFormat[register.format], getDateTime()) @@ -678,8 +504,7 @@ def generateBeckhoffRegisters(paramClass, deviceDOM, block, deviceIndex, deploy, return source # ---------------------------------------------------- -def generateBeckhoffSources(paramDOM, sourceFolderPath, logTopics): - deploy = getDeploymentInformation(paramDOM) +def generateBeckhoffSources(param, sourceFolderPath, logTopics): # Prepare the global variables source (<.exp> file) with its diagnostic data-block header source ="""(* +-------------------------------------------------------------------\r\n""" @@ -688,50 +513,33 @@ def generateBeckhoffSources(paramDOM, sourceFolderPath, logTopics): source += """* | April 2015\r\n""" source += """* +-------------------------------------------------------------------\r\n""" source += """*\r\n""" - source += """* Release : SILECS_%s\r\n"""%(deploy.silecsVersion) + source += """* Release : SILECS_%s\r\n"""%(param.silecsVersion) source += """*)""" source += '\r\nVAR_GLOBAL\r\n' - for paramClass in ParamClass.getParamClassesFromRootNode(paramDOM): + for paramClass in param.controller.paramClasses: deviceDOMList = paramClass.getDeviceInstanceNodes() # get Device instances of that class # Device mode is not supported for Beckhoff PLCs - Only block mode available for block in paramClass.getParamBlocks(): for deviceIndex, deviceDOM in enumerate(deviceDOMList): - source += generateBeckhoffRegisters(paramClass, deviceDOM, block, deviceIndex,deploy,logTopics) + source += generateBeckhoffRegisters(param, paramClass, deviceDOM, block, deviceIndex,logTopics) source += 'END_VAR' # Write the source into the EXP source file - generateControllerFiles(sourceFolderPath,deploy,".exp",source,logTopics); + generateControllerFiles(sourceFolderPath,param.controller.hostName,".exp",source,logTopics); #------------------------------------------------------------------------- # NI code generation #------------------------------------------------------------------------- -def generateNISources(paramDOM, sourceFolderPath ,logTopics): +def generateNISources(param, sourceFolderPath ,logTopics): iecommon.logInfo("PLC source generation not available for National Instruments equipment",logTopics) return -def getDeploymentInformation(paramDOM): - deploy = DeploymentInfo() - mapping = paramDOM.xpathEval("/SILECS-Param/SILECS-Mapping")[0] - - deploy.plcModel = mapping.prop('plc-model') - deploy.plcSystem = mapping.prop('plc-system') - deploy.plcProtocol = mapping.prop('protocol') - deploy.plcName = mapping.prop('plc-name') - deploy.address = mapping.prop('address') - ownerNode = paramDOM.xpathEval("/SILECS-Param/Mapping-Info/Owner")[0] - deploy.owner = ownerNode.prop('user-login') - deploymentNode = paramDOM.xpathEval("/SILECS-Param/Mapping-Info/Deployment")[0] - deploy.checksum = long(deploymentNode.prop('checksum')) - rootNode = paramDOM.xpathEval("/SILECS-Param")[0] - deploy.silecsVersion = rootNode.prop("silecs-version") - return deploy - -def generateControllerFiles(sourceFolderPath,deploy,fileExtention,source,logTopics={'errorlog': True}): - fileName = deploy.plcName + fileExtention +def generateControllerFiles(sourceFolderPath,hostName,fileExtention,source,logTopics={'errorlog': True}): + fileName = hostName + fileExtention fullFilePath = os.path.normpath(sourceFolderPath + "/" + fileName ) iecommon.logInfo("Generate PLC sources: %s" %fullFilePath,logTopics); @@ -740,25 +548,23 @@ def generateControllerFiles(sourceFolderPath,deploy,fileExtention,source,logTopi fdesc.close() # Needed for unit-testing -def generateControllerCode(controller, paramsFile, sourceFolderPath, logTopics={'errorlog': True}): - paramDOM = libxml2.parseFile(paramsFile) +def generateControllerCode(controller, param, sourceFolderPath, logTopics={'errorlog': True}): if controller.plcNode.get_name() == 'Siemens-PLC': - generateSiemensSources(paramDOM,sourceFolderPath,logTopics) + generateSiemensSources(param,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'PC-Controller': - generatePCLikeSources(paramDOM,sourceFolderPath,logTopics) - elif controller.plcNode.get_name() == 'VirtualS7': - generateVirtualS7Sources(paramDOM,sourceFolderPath,logTopics) + generatePCLikeSources(param,sourceFolderPath,logTopics) + elif controller.plcNode.get_name() == 'Virtual-Controller': + generateVirtualS7Sources(param,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'Schneider-PLC': - generateSchneiderSources(paramDOM,sourceFolderPath,logTopics) + generateSchneiderSources(param,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'Rabbit-uC': - generateRabbitSources(paramDOM,sourceFolderPath,logTopics) + generateDIGISources(param,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'Beckhoff-PLC': - generateBeckhoffSources(paramDOM,sourceFolderPath,logTopics) + generateBeckhoffSources(param,sourceFolderPath,logTopics) elif controller.plcNode.get_name() == 'NI-Controller': - generateNISources(paramDOM,sourceFolderPath,logTopics) + generateNISources(param,sourceFolderPath,logTopics) else: - iecommon.logError("The PLC-Type %s is not supported" %plcNode.get_name(), True,logTopics) - paramDOM.freeDoc() + iecommon.logError("The PLC-Type: '" + controller.plcNode.get_name() + "' is not supported", True,logTopics) #========================================================================= # Entry Point @@ -775,7 +581,12 @@ def genPlcSrc(workspacePath, deployName,silecsVersion,logTopics={'errorlog': Tru silecsDeploy = Deploy.getDeployFromFile(deployFilePath) for controller in silecsDeploy.controllers: paramsFile = iefiles.getParameterFile(workspacePath, deployName,controller.hostName) - generateControllerCode(controller,paramsFile,sourceFolderPath,logTopics) + paramDOM = libxml2.parseFile(paramsFile) + param = Param(paramDOM) + param.deployName = silecsDeploy.name + param.deployVersion = silecsDeploy.version + generateControllerCode(controller,param,sourceFolderPath,logTopics) + paramDOM.freeDoc() return "Genplcsrc succeded!" diff --git a/silecs-codegen/src/xml/model/Class/Class.py b/silecs-codegen/src/xml/model/Class/Class.py index 2794060451a68533ef45ab91296fc19d8351fedc..7af201c8f6e760a08cd7d6cdeb0fde32bb8df2ba 100644 --- a/silecs-codegen/src/xml/model/Class/Class.py +++ b/silecs-codegen/src/xml/model/Class/Class.py @@ -71,18 +71,6 @@ class ParamClass(Class): deviceNodes = self.xmlNode.xpathEval("Instance") return deviceNodes - @staticmethod - def getParamClassesFromRootNode(silecsRoot): - classNodes = silecsRoot.xpathEval("/SILECS-Param/SILECS-Mapping/SILECS-Class") - if len(classNodes) < 1: - raise BaseException("Error: no class-node found in design-document") - paramClasses = [] - for classNode in classNodes: - paramClass = ParamClass() - paramClass.initWithParamClassNode(classNode) - paramClasses.append(paramClass) - return paramClasses - class DesignClass(Class): def __init__(self, xmlNode): diff --git a/silecs-codegen/src/xml/model/Deploy/Controller.py b/silecs-codegen/src/xml/model/Deploy/Controller.py index 83f710347af102a7dea11bbb5cd8a4ec2ff2a336..0d4a40cdc42505d440c672bb0af6fcba68242a50 100644 --- a/silecs-codegen/src/xml/model/Deploy/Controller.py +++ b/silecs-codegen/src/xml/model/Deploy/Controller.py @@ -152,5 +152,5 @@ class NIController(Controller): self.brand = "NI" self.baseAddress = 0 - + #xmlNode.shellPrintNode() diff --git a/silecs-codegen/src/xml/model/Param/Controller.py b/silecs-codegen/src/xml/model/Param/Controller.py new file mode 100644 index 0000000000000000000000000000000000000000..21ec8a3f7d1ef72c5fd20f9471ba5aaf62e6de87 --- /dev/null +++ b/silecs-codegen/src/xml/model/Param/Controller.py @@ -0,0 +1,47 @@ +#!/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/>. + +from model.Class.Class import ParamClass +import libxml2 + +class Controller(object): + + def __init__(self, xmlNode): + self.hostName = "" + self.domain = "" + self.system = "" + self.model = "" + self.protocol = "" + self.brand = "" + self.address = long(0) + self.usedMem = long(0) + self.xmlNode = None + self.paramClasses = [] + + self.xmlNode = xmlNode + self.hostName = xmlNode.prop("plc-name") + self.domain = xmlNode.prop("domain") + self.system = self.xmlNode.prop('plc-system') + 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.usedMem = self.xmlNode.prop("used-mem") + + for classNode in self.xmlNode.xpathEval('SILECS-Class'): + paramClass = ParamClass() + paramClass.initWithParamClassNode(classNode) + self.paramClasses.append(paramClass) \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Param/Param.py b/silecs-codegen/src/xml/model/Param/Param.py new file mode 100644 index 0000000000000000000000000000000000000000..ce952f934f94e946f07cf40edc555578cdf24ee5 --- /dev/null +++ b/silecs-codegen/src/xml/model/Param/Param.py @@ -0,0 +1,53 @@ +#!/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/>. + +import libxml2 + +from model.Param.Controller import Controller + +class Param(object): + + def __init__(self, xmlNode): + self.silecsVersion = "" + self.owner = "" + self.genDate = "" + self.checksum = 0 + self.controller = None + self.deployName ="" #need to be explicitly set by codegen + self.deployVersion ="" #need to be explicitly set by codegen + self.xmlNode = xmlNode + paramNodes = self.xmlNode.xpathEval('/SILECS-Param') + if len(paramNodes) != 1: + raise Exception( "Error: param-document is corrupt" ) + paramNode = paramNodes[0] + ownderNodes = paramNode.xpathEval('Mapping-Info/Owner') + if len(ownderNodes) != 1: + raise Exception( "Error: param-document is corrupt" ) + generationNodes = paramNode.xpathEval('Mapping-Info/Generation') + if len(generationNodes) != 1: + raise Exception( "Error: param-document is corrupt" ) + deploymentNodes = paramNode.xpathEval('Mapping-Info/Deployment') + if len(deploymentNodes) != 1: + raise Exception( "Error: param-document is corrupt" ) + mappingNodes = paramNode.xpathEval('SILECS-Mapping') + if len(mappingNodes) != 1: + raise Exception( "Error: param-document is corrupt" ) + + self.silecsVersion = paramNode.prop("silecs-version") + self.owner = ownderNodes[0].prop("user-login") + self.genDate = generationNodes[0].prop("date") + self.checksum = long(deploymentNodes[0].prop('checksum')) + self.controller = Controller(mappingNodes[0]) \ No newline at end of file diff --git a/silecs-codegen/src/xml/model/Param/__init__.py b/silecs-codegen/src/xml/model/Param/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy index ccf5e18e1095386cfcecb0997ac38e3aa8474075..0c5dbffbf80c077a1484af4416efda8412ad3606 100644 --- a/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy +++ b/silecs-codegen/src/xml/test/AllTypesDU.silecsdeploy @@ -37,17 +37,17 @@ </Controller> <Controller host-name="Virtual_SiemensDevice"> - <PC-Controller model="Linux_x64" system="S7 virtual controller" protocol="DEVICE_MODE" base-address="0"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="DEVICE_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> - </PC-Controller> + </Virtual-Controller> </Controller> <Controller host-name="Virtual_SiemensBlock"> - <PC-Controller model="Linux_x64" system="S7 virtual controller" protocol="BLOCK_MODE" base-address="0"> + <Virtual-Controller model="SIMATIC_S7-VIRTUAL" system="S7 virtual controller" protocol="BLOCK_MODE" base-address="0"> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice1" /> <Device silecs-design-ref="AllTypes" silecs-device-label="testDevice2" /> - </PC-Controller> + </Virtual-Controller> </Controller> <Controller host-name="Beckhoff_BC9020"> <Beckhoff-PLC model="BC9020" system="TWINCat" protocol="BLOCK_MODE" base-address="0"> diff --git a/silecs-codegen/src/xml/test/general/genplcsrcTest.py b/silecs-codegen/src/xml/test/general/genplcsrcTest.py index 73cc09755079174cd7e4af471d88e11e75513c08..7190864762b9747f99d6236f18d148a8de75acc9 100644 --- a/silecs-codegen/src/xml/test/general/genplcsrcTest.py +++ b/silecs-codegen/src/xml/test/general/genplcsrcTest.py @@ -23,6 +23,7 @@ import genplcsrc import iecommon import iefiles from model.Deploy.Deploy import Deploy +from model.Param.Param import Param import libxml2 @@ -37,7 +38,11 @@ def generatePLCSources(): silecsDeploy = Deploy.getDeployFromFile(testFolder + "/AllTypesDU.silecsdeploy") for controller in silecsDeploy.controllers: paramsFile = generationFolder + "/client/" + controller.hostName + ".silecsparam" - genplcsrc.generateControllerCode(controller, paramsFile, generationFoldeController ,{'errorlog': True}) + paramDOM = libxml2.parseFile(paramsFile) + param = Param(paramDOM) + param.deployName = silecsDeploy.name + param.deployVersion = silecsDeploy.version + genplcsrc.generateControllerCode(controller, param, generationFoldeController ,{'errorlog': True}) def CompareGeneratedFiles(hostName,fileExtension): 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 f8666ab53e46cc0d1970242f9dacc84b55b96ea4..161f848188630bcd335b864d2b27d2390a242756 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 @@ -5,7 +5,7 @@ <Generation date="2017-07-20 10:34:35.299118"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_BlockMode" plc-brand="PCLike" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="BLOCK_MODE" address="0" domain="" used-mem="TODO"> + <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"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> 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 1a75876058b1a9f5baee3408d68aa21162f9809e..c762cf3a2d749f31bfcab68027c0c19dc4e600ac 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 @@ -5,7 +5,7 @@ <Generation date="2017-07-20 10:34:35.271989"/> <Deployment checksum="308863231"/> </Mapping-Info> - <SILECS-Mapping plc-name="Rabbit_DeviceMode" plc-brand="PCLike" plc-system="Standard-C" plc-model="Rabbit_RCM_4010" protocol="DEVICE_MODE" address="0" domain="" used-mem="TODO"> + <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"> <Acquisition-Block name="hdrBlk" size="14" address="0" mem-size="44"> <Acquisition-Register name="_version" size="1" address="0" mem-size="16"> diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h index a5857abf63b31fa1699601a15005f03e69f4beeb..4cf18736d2bb8c2c9ffe6fb5aaf0cef4447d2e3e 100644 --- a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h +++ b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_BlockMode.h @@ -5,7 +5,7 @@ * | April 2015 * +------------------------------------------------------------------- * - * Release : SILECS_DEV + * Release : DEV * * The following code has been automatically generated by SILECS. * @@ -26,14 +26,14 @@ typedef struct { - uint8_t sc_100; // second cent - uint8_t sc; // second - uint8_t mn; // minute - uint8_t hh; // hour - uint8_t dd; // day - uint8_t mm; // month - uint8_t yy1; // year - uint8_t yy2; // year2 + uint8_t sc_100; // second cent + uint8_t sc; // second + uint8_t mn; // minute + uint8_t hh; // hour + uint8_t dd; // day + uint8_t mm; // month + uint8_t yy1; // year + uint8_t yy2; // year2 } dt; #define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F)) @@ -41,14 +41,14 @@ typedef struct void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date) { - date->sc_100 = sc_100; - date->sc = _tobcd(sc); - date->mn = _tobcd(mn); - date->hh = _tobcd(hh); - date->dd = _tobcd(dd); - date->mm = _tobcd(mm); - date->yy2 = _tobcd((int8_t)(yy/100)); - date->yy1 = _tobcd((int8_t)(yy%100)); + date->sc_100 = sc_100; + date->sc = _tobcd(sc); + date->mn = _tobcd(mn); + date->hh = _tobcd(hh); + date->dd = _tobcd(dd); + date->mm = _tobcd(mm); + date->yy2 = _tobcd((int8_t)(yy/100)); + date->yy1 = _tobcd((int8_t)(yy%100)); } @@ -179,17 +179,17 @@ union modbus_data { /* Initialization function */ int SILECS_init() { - /* Silecs version initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "SILECS_DEV"); - - /* Silecs checksum initialization */ - silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = 308863231; - - /* Silecs user initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "schwinn"); - - /* Silecs date initialization */ - SILECS_set_dt(3,3,38,16,8,6,2017,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date); + /* Silecs version initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "SILECS_DEV"); + + /* Silecs checksum initialization */ + silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = 308863231; + + /* Silecs user initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "schwinn"); + + /* Silecs date initialization */ + SILECS_set_dt(3,3,38,16,8,6,2017,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date); } /* diff --git a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h index 95491d747e28f33f3618ed1e6afda28e4a3fe2f8..d0bf246979c9c32afd013e5e43a9cf7ee156e9f7 100644 --- a/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h +++ b/silecs-codegen/src/xml/test/generated_correct/controller/Rabbit_DeviceMode.h @@ -5,7 +5,7 @@ * | April 2015 * +------------------------------------------------------------------- * - * Release : SILECS_DEV + * Release : DEV * * The following code has been automatically generated by SILECS. * @@ -26,14 +26,14 @@ typedef struct { - uint8_t sc_100; // second cent - uint8_t sc; // second - uint8_t mn; // minute - uint8_t hh; // hour - uint8_t dd; // day - uint8_t mm; // month - uint8_t yy1; // year - uint8_t yy2; // year2 + uint8_t sc_100; // second cent + uint8_t sc; // second + uint8_t mn; // minute + uint8_t hh; // hour + uint8_t dd; // day + uint8_t mm; // month + uint8_t yy1; // year + uint8_t yy2; // year2 } dt; #define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F)) @@ -41,14 +41,14 @@ typedef struct void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_t mm,int32_t yy, dt *date) { - date->sc_100 = sc_100; - date->sc = _tobcd(sc); - date->mn = _tobcd(mn); - date->hh = _tobcd(hh); - date->dd = _tobcd(dd); - date->mm = _tobcd(mm); - date->yy2 = _tobcd((int8_t)(yy/100)); - date->yy1 = _tobcd((int8_t)(yy%100)); + date->sc_100 = sc_100; + date->sc = _tobcd(sc); + date->mn = _tobcd(mn); + date->hh = _tobcd(hh); + date->dd = _tobcd(dd); + date->mm = _tobcd(mm); + date->yy2 = _tobcd((int8_t)(yy/100)); + date->yy1 = _tobcd((int8_t)(yy%100)); } @@ -172,17 +172,17 @@ union silecsData { /* Initialization function */ int SILECS_init() { - /* Silecs version initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "SILECS_DEV"); - - /* Silecs checksum initialization */ - silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = 308863231; - - /* Silecs user initialization */ - strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "schwinn"); - - /* Silecs date initialization */ - SILECS_set_dt(3,3,38,16,8,6,2017,&silecsData.data.SilecsHeader_device[0].hdrBlk._date); + /* Silecs version initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "SILECS_DEV"); + + /* Silecs checksum initialization */ + silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = 308863231; + + /* Silecs user initialization */ + strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "schwinn"); + + /* Silecs date initialization */ + SILECS_set_dt(0,27,37,16,24,7,2017,&silecsData.data.SilecsHeader_device[0].hdrBlk._date); } /*