Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • silecs/opensilecs
  • k.fugiel/opensilecs
  • s.kupiecki/opensilecs
3 results
Show changes
Showing
with 1490 additions and 1805 deletions
#!/bin/sh
set -e
CPU="x86_64"
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT") # path where this script is located in
#SNAP7_PATH=${SCRIPTPATH}/../../../git/snap7/snap7-full/build/bin/${CPU}-linux #local
SNAP7_PATH=${SCRIPTPATH}/../../../snap7/2.0.0/bin/${CPU}-linux
#BINARY="${SCRIPTPATH}/../build/bin/${CPU}/silecs-cli-client" #local
BINARY="${SCRIPTPATH}/../bin/${CPU}/silecs-cli-client"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP7_PATH
echo "##### LD_LIBRARY_PATH: ###################################################################################"
echo "$LD_LIBRARY_PATH"
echo "##########################################################################################################"
echo ""
PARAM_FILE=/common/home/bel/schwinn/lnx/workspace-silecs-neon/SiemensTestDU/generated/client/tsts7001.silecsparam
REGISTER=DQ_Anlog00
DEVICE=MyDevice1
......
#!/bin/sh
set -e
CPU="x86_64"
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT") # path where this script is located in
#SNAP7_PATH=${SCRIPTPATH}/../../../git/snap7/snap7-full/build/bin/${CPU}-linux #local
SNAP7_PATH=${SCRIPTPATH}/../../../snap7/2.0.0/bin/${CPU}-linux
#BINARY="${SCRIPTPATH}/../build/bin/${CPU}/silecs-cli-client" #local
BINARY="${SCRIPTPATH}/../bin/${CPU}/silecs-cli-client"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP7_PATH
echo "##### LD_LIBRARY_PATH: ###################################################################################"
echo "$LD_LIBRARY_PATH"
echo "##########################################################################################################"
echo ""
PARAM_FILE=/common/home/bel/schwinn/lnx/workspace-silecs-neon/SiemensTestDU/generated/client/tsts7001.silecsparam
# config for SiemensTestDU
......
#!/bin/sh
set -e
INSTALL_DIR=$1
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT") # path where this script is located in
mkdir -p ${INSTALL_DIR}
cp -r ${SCRIPTPATH}/build/bin ${INSTALL_DIR}
cp -r ${SCRIPTPATH}/examples ${INSTALL_DIR}
\ No newline at end of file
**/*.pyc
**/*__pycache__
\ No newline at end of file
cmake_minimum_required(VERSION 3.20.2)
project(silecs-codegen)
find_package(Python COMPONENTS Interpreter)
add_test (NAME codegen-tests
COMMAND ${Python_EXECUTABLE} -m unittest
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/xml/
)
install (
DIRECTORY ${PROJECT_SOURCE_DIR}/src/xml
DESTINATION ${CMAKE_PROJECT_VERSION}/${PROJECT_NAME}
FILES_MATCHING PATTERN "*.py*")
This diff is collapsed.
# silecs-codegen
This component of the SILECS PLC-framework generates FESA and stand-alone C++ code from an existing silecs-project in order to ease the usage of the package silecs-communication-cpp
This component of the opensilecs PLC-framework generates FESA and stand-alone C++ code from an existing silecs-project in order to ease the usage of the package silecs-communication-cpp
## Getting Started
## Tests
Please check the lab-specific SILECS-Wikis for more information:
In [test](src/xml/test/) directory there are files with {test_name} which contain unit tests written using `unittest` framework. Tests conserning the migration tools are in their own corresponding folders inside [migration](src/xml/migration/).
[CERN SILECS Wiki Page][CERN_Wiki]
[GSI SILECS Wiki Page][GSI_Wiki]
## License
Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. See the [LICENSE file][license] for details.
[license]: LICENSE
[CERN_Wiki]: https://wikis.cern.ch/display/SIL/SILECs+Home
[GSI_Wiki]: https://www-acc.gsi.de/wiki/Frontend/SILECS
All tests can be run together using following command from inside [src/xml](src/xml/):
```
python3 -m unittest
```
#!/bin/sh
set -e
INSTALL_DIR=$1
SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT") # path where this script is located in
mkdir -p ${INSTALL_DIR}
cp -r ${SCRIPTPATH}/src/xml ${INSTALL_DIR}
\ No newline at end of file
......@@ -9,6 +9,7 @@
# be specialized on call to append the string to be stored in the file.
#
import string
import time
......@@ -54,17 +55,17 @@ def toWordArray(strg):
#=========================================================================
# C Source template (.c file)
#=========================================================================
header = """
header = string.Template("""
/* +-------------------------------------------------------------------
* | Copyright CERN 2015
* | SILECS - BE/CO-SRC
* | April 2015
* +-------------------------------------------------------------------
*
* Release : %s
* Release : ${silecsRelease}
*
* The following code has been automatically generated by SILECS.
* Code regeneration will overwrite it.
*
* N.B: This file relies on the existence of explicit C data type such
* as int8_t, uint8_t, int16_t, etc....
......@@ -73,7 +74,7 @@ header = """
* web page before including this header file.
*/
#define MODBUS_START_ADDRESS %s
#define MODBUS_START_ADDRESS ${baseAddress}
/*---------------------------------------------------------------------
* DT
......@@ -94,7 +95,7 @@ typedef struct
} dt;
#define _frombcd(a) (int)(((a>>4)*10)+(a&0x0F))
#define _tobcd(a) (((unsigned char)((a)/10)<<4)+((a)%%10))
#define _tobcd(a) (((unsigned char)((a)/10)<<4)+((a)%10))
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)
{
......@@ -105,80 +106,72 @@ void SILECS_set_dt(int8_t sc_100 ,int8_t sc, int8_t mn,int8_t hh,int8_t dd,int8_
date->dd = _tobcd(dd);
date->mm = _tobcd(mm);
date->yy2 = _tobcd((int8_t)(yy/100));
date->yy1 = _tobcd((int8_t)(yy%%100));
date->yy1 = _tobcd((int8_t)(yy%100));
}
"""
""")
#=========================================================================
# DATA TYPE DEFINITION
#=========================================================================
firstBlockUDT = """
firstBlockUDT = string.Template("""
/*---------------------------------------------------------------------
* %s / v%s
* ${className} / v${classVersion}
* BLOCK Type definition
*---------------------------------------------------------------------
*/
"""
""")
blockUDT = """
blockUDT = string.Template("""
typedef struct
{
%s
} _%s_%s;
"""
$regList
} _${className}_${blockName};
""")
regScalar = """ %s %s;
"""
regScalar = string.Template(""" ${regFormat} ${regName};
""")
regArray = """ %s %s[%s];
"""
regArray = string.Template(""" ${regFormat} ${regName}[${strLen}];
""")
regArray2d = """ %s %s[%s][%s];
"""
regArray2d = string.Template(""" ${regFormat} ${regName}[${regDim}][${strLen}];
""")
stringArray = """ %s %s[%s][%s][%s];
"""
stringArray = string.Template(""" ${regFormat} ${regName}[${regDim}][${regDim2}][${strLen}];
""")
#=========================================================================
# INSTANTIATION
#=========================================================================
allocationComment = """
allocationComment = string.Template("""
/*---------------------------------------------------------------------
* MEMORY ALLOCATION
* PROTOCOL: %s
* PROTOCOL: ${plcProtocol}
*---------------------------------------------------------------------
*/
"""
""")
#======= DEVICE MODE =================
deviceModeBlockInstantiation = string.Template(""" _${className}_${blockName} ${blockName};
""")
deviceModeBlockInstantiation = """ _%s_%s %s;
"""
#deviceModeClass_deviceNumber = """
# struct {
# _%s_%s %s;
# } %s_device[%s];
#"""
deviceModeClass_deviceNumber = """
deviceModeClass_deviceNumber = string.Template("""
struct {
%s
} %s_device[NB_%s_DEVICE];
"""
deviceModeClass_deviceList = """
${blockList}
} ${className}_device[NB_${className}_DEVICE];
""")
deviceModeClass_deviceList = string.Template("""
struct {
%s
} %s;
"""
${blockList}
} ${deviceList};
""")
deviceMode_dataInstantiation = """
deviceMode_dataInstantiation = string.Template("""
typedef struct {
%s
${classList}
} _SILECS_DATA_SEGMENT;
#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
......@@ -188,21 +181,20 @@ union silecsData {
uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
} silecsData;
"""
""")
#======= BLOCK MODE =================
blockModeDeviceInstantiation_deviceList = string.Template(""" _${className}_${blockName} ${deviceName};
""")
blockModeDeviceInstantiation_deviceList = """ _%s_%s %s;
"""
blockModeBlockInstantiation = """
blockModeBlockInstantiation = string.Template("""
struct {
%s } %s_%s;
"""
${deviceList} } ${className}_${blockName};
""")
blockMode_dataInstantiation = """
blockMode_dataInstantiation = string.Template("""
typedef struct {
%s
${classList}
} _SILECS_DATA_SEGMENT;
#define SILECS_DATA_SEGMENT_MODBUS_SIZE (sizeof(_SILECS_DATA_SEGMENT)/2)
......@@ -212,7 +204,7 @@ union modbus_data {
uint16_t array[SILECS_DATA_SEGMENT_MODBUS_SIZE];
} silecsData;
"""
""")
#=========================================================================
# init
......@@ -223,44 +215,43 @@ globalAllocation = """
uint16_t modbus_data = & data;
"""
initFunctionDeviceMode = """
initFunctionDeviceMode = string.Template("""
/* Initialization function */
int SILECS_init()
{
/* Silecs version initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._version, "${version}");
/* Silecs checksum initialization */
silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = %s;
silecsData.data.SilecsHeader_device[0].hdrBlk._checksum = ${checksum};
/* Silecs user initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_device[0].hdrBlk._user, "${user}");
/* Silecs date initialization */
SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
SILECS_set_dt(${dt6},${dt5},${dt4},${dt3},${dt2},${dt1},${dt0},&silecsData.data.SilecsHeader_device[0].hdrBlk._date);
}
"""
""")
#initFunctionBlockMode = """
initFunctionBlockMode = """
initFunctionBlockMode = string.Template("""
/* Initialization function */
int SILECS_init()
{
/* Silecs version initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._version, "${version}");
/* Silecs checksum initialization */
silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = %s;
silecsData.data.SilecsHeader_hdrBlk.device[0]._checksum = ${checksum};
/* Silecs user initialization */
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "%s");
strcpy((unsigned char *)silecsData.data.SilecsHeader_hdrBlk.device[0]._user, "${user}");
/* Silecs date initialization */
SILECS_set_dt(%s,%s,%s,%s,%s,%s,%s,&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
SILECS_set_dt(${dt6},${dt5},${dt4},${dt3},${dt2},${dt1},${dt0},&silecsData.data.SilecsHeader_hdrBlk.device[0]._date);
}
"""
""")
#=========================================================================
# Example generation
......@@ -270,19 +261,19 @@ instantiationExample = """/*
* Automatically generated Addressing example
*"""
deviceModeDeviceListExample = """
* This example shows how to address the register %s of block %s
* of device %s of the class %s
deviceModeDeviceListExample = string.Template("""
* This example shows how to address the register ${registerName} of block ${blockName}
* of device ${deviceLabel} of the class ${className}
*
* silecsData.%s_%s.%s.%s = ....;
*/"""
* silecsData.${className}_${deviceLabel}.${blockName}.${registerName} = ....;
*/""")
blockModeDeviceListExample = """
* This example shows how to address the register %s of block %s
* of device %s of the class %s
blockModeDeviceListExample = string.Template("""
* This example shows how to address the register ${registerName} of block ${blockName}
* of device ${deviceLabel} of the class ${className}
*
* silecsData.%s_%s.%s.%s = ....;
*/"""
* silecsData.${className}_${blockName}.${deviceLabel}.${registerName} = ....;
*/""")
#=========================================================================
# C code generation Sub-function
......@@ -290,33 +281,33 @@ blockModeDeviceListExample = """
# HEADER file ------------------------------------------------------------
def cHeader(silecsRelease, baseAddress):
return header %(silecsRelease, baseAddress)
return header.substitute(silecsRelease=silecsRelease, baseAddress=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 %(whichDIGIFormat[regFormat], regName, regDim, regDim2, strLen)
return stringArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, regDim2=regDim2, strLen=strLen)
elif regDim > 1: # reuse the array2D syntax
return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, strLen)
return regArray2d.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, strLen=strLen)
else: # regular string register
return regArray %(whichDIGIFormat[regFormat], regName, strLen)
return regArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, strLen=strLen)
else:
if regDim == 1 and regDim2 == 1: # scalar
return regScalar %(whichDIGIFormat[regFormat], regName)
return regScalar.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName)
elif regDim > 1 and regDim2 == 1: # array
return regArray %(whichDIGIFormat[regFormat], regName, regDim)
return regArray.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, strLen=regDim)
else: # dim1>=1 and for whatever dim2, use double array syntax
return regArray2d %(whichDIGIFormat[regFormat], regName, regDim, regDim2)
return regArray2d.substitute(regFormat=whichDIGIFormat[regFormat], regName=regName, regDim=regDim, strLen=regDim2)
def cFirstBlockUDT(className, classVersion):
return firstBlockUDT %(className, classVersion)
return firstBlockUDT.substitute(className=className, classVersion=classVersion)
# BLOCK type definition (UDT) --------------------------------------------
def cBlockUDT(className, blockName, regList):
return blockUDT %(regList, className, blockName)
return blockUDT.substitute(regList=regList, className=className, blockName=blockName)
#============= DEVICE instantiation =============
......@@ -324,46 +315,46 @@ def cBlockUDT(className, blockName, regList):
# GLOBAL instantiation ----------------------------------------------
def cAllocationComment(plcProtocol):
return allocationComment %(plcProtocol)
return allocationComment.substitute(plcProtocol=plcProtocol)
# DEVICE MODE instantiation ----------------------------------------------
def cDeviceModeBlockInstantiation(className, blockName):
return deviceModeBlockInstantiation %(className, blockName, blockName)
return deviceModeBlockInstantiation.substitute(className=className, blockName=blockName)
def cDeviceModeClass_deviceNumber(className, blockList):
return deviceModeClass_deviceNumber %(blockList, className, className)
return deviceModeClass_deviceNumber.substitute(blockList=blockList, className=className)
def cDeviceModeClass_deviceList(blockList, deviceList):
return deviceModeClass_deviceList %(blockList, deviceList)
return deviceModeClass_deviceList.substitute(blockList=blockList, deviceList=deviceList)
def cDeviceModeDataInstantiation(classList):
return deviceMode_dataInstantiation %(classList)
return deviceMode_dataInstantiation.substitute(classList=classList)
# BLOCK MODE instantiation ----------------------------------------------
def cBlockModeDeviceInstantiation_deviceList(className, blockName, deviceName):
return blockModeDeviceInstantiation_deviceList %(className, blockName, deviceName)
return blockModeDeviceInstantiation_deviceList.substitute(className=className, blockName=blockName, deviceName=deviceName)
def cBlockModeBlockInstantiation(deviceList, className, blockName):
return blockModeBlockInstantiation %(deviceList, className, blockName)
return blockModeBlockInstantiation.substitute(deviceList=deviceList, className=className, blockName=blockName)
def cBlockModeDataInstantiation(classList):
return blockMode_dataInstantiation %(classList)
return blockMode_dataInstantiation.substitute(classList=classList)
# Init Function ----------------------------------------------
def cInitDeviceMode(ieVersion,ieChecks,ieUser):
dt = time.localtime(time.time())
return initFunctionDeviceMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
return initFunctionDeviceMode.substitute(version="SILECS_"+ieVersion, checksum=ieChecks, user=ieUser, dt6=dt[6], dt5=dt[5], dt4=dt[4], dt3=dt[3], dt2=dt[2], dt1=dt[1], dt0=dt[0])
def cInitBlockMode(ieVersion,ieChecks,ieUser):
dt = time.localtime(time.time())
return initFunctionBlockMode %("SILECS_"+ieVersion,ieChecks,ieUser,dt[6],dt[5],dt[4],dt[3],dt[2],dt[1],dt[0])
return initFunctionBlockMode.substitute(version="SILECS_"+ieVersion, checksum=ieChecks, user=ieUser, dt6=dt[6], dt5=dt[5], dt4=dt[4], dt3=dt[3], dt2=dt[2], dt1=dt[1], dt0=dt[0])
# Example function ----------------------------------------------
def cExample(plcProtocol,className, blockName, registerName, deviceLabel =''):
if plcProtocol == 'DEVICE_MODE':
return instantiationExample + deviceModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, deviceLabel, blockName, registerName)
return instantiationExample + deviceModeDeviceListExample.substitute(registerName=registerName, blockName=blockName, deviceLabel=deviceLabel, className=className)
else:
return instantiationExample + blockModeDeviceListExample %(registerName, blockName, deviceLabel, className, className, blockName, deviceLabel, registerName)
return instantiationExample + blockModeDeviceListExample.substitute(registerName=registerName, blockName=blockName, deviceLabel=deviceLabel, className=className)
#!/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
......@@ -33,9 +33,9 @@ from iecommon import *
# Generates two Makefile.specific, one for the class design
# and another for the deploy unit
#-------------------------------------------------------------------------
def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
# Generate makefile for class design
source = fesaTemplates.genMakeDesign(centralMakefilePath)
source = fesaTemplates.genMakeDesign()
makefile = projectPath + "/" + "Makefile.specific"
if os.path.isfile(makefile): #dont overwrite
return
......@@ -44,9 +44,9 @@ def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': Tr
fdesc.write(source)
fdesc.close()
def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
# Generate makefile for class design
source = fesaTemplates.genMakeDeploy(silecsBasePath,snap7BasePath)
source = fesaTemplates.genMakeDeploy()
# Write file and save
makefile = projectPath + "/" + "Makefile.specific"
if os.path.isfile(makefile): #dont overwrite
......
......@@ -26,7 +26,7 @@ import datetime
import socket
import iecommon
import fesaTemplates
import fesa.fesa_3_0_0.fesaTemplates
import iefiles
from iecommon import *
......@@ -87,8 +87,29 @@ class FESADesignGenerator3_0_0(object):
fillAttributes(scalarNode, {'type': register.getFesaType()})
return scalarNode
def getOrCreateType(self,fieldNode,register):
if register.valueType == "scalar":
def getOrCreateCustomScalarType(self, fieldNode, register):
scalarNode = getOrCreateChildElement(fieldNode,'custom-type-scalar')
fillAttributes(scalarNode, {'data-type-name-ref': register.custom_type_name})
return scalarNode
def getOrCreateCustomArrayType(self,fieldNode,register):
arrayNode = getOrCreateChildElement(fieldNode,'custom-type-array')
fillAttributes(arrayNode, {'data-type-name-ref': register.custom_type_name})
dimNode = getOrCreateChildElement(arrayNode,'dim')
dimNode.setContent(str(register.dim1))
return arrayNode
def getOrCreateCustom2DArrayType(self,fieldNode,register):
array2DNode = getOrCreateChildElement(fieldNode,'custom-type-array2D')
fillAttributes(array2DNode, {'data-type-name-ref': register.custom_type_name})
dim1Node = getOrCreateChildElement(array2DNode,'dim1')
dim2Node = getOrCreateChildElement(array2DNode,'dim2')
dim1Node.setContent(str(register.dim1))
dim2Node.setContent(str(register.dim2))
return array2DNode
def getOrCreateType(self,fieldNode, register):
if register.valueType == "scalar":
return self.getOrCreateScalarType(fieldNode,register)
elif register.valueType == "array":
return self.getOrCreateArrayType(fieldNode,register)
......@@ -100,6 +121,12 @@ class FESADesignGenerator3_0_0(object):
return self.getOrCreateStringArrayType(fieldNode,register)
elif register.valueType == "stringArray2D":
iecommon.logError('ERROR: In register '+register.name+' - 2D array of strings not supported in FESA.', True, {'errorlog': True})
elif register.valueType == "custom-type-scalar":
return self.getOrCreateCustomScalarType(fieldNode, register)
elif register.valueType == "custom-type-array":
return self.getOrCreateCustomArrayType(fieldNode, register)
elif register.valueType == "custom-type-array2D":
return self.getOrCreateCustom2DArrayType(fieldNode, register)
else:
iecommon.logError('ERROR: Unknown data-type:' + register.valueType, True, {'errorlog': True})
return None
......@@ -197,6 +224,10 @@ class FESADesignGenerator3_0_0(object):
else:
return getOrCreateNamedChildElement(parent,'field',register.getFesaFieldName())
def addDefaultNode(self, fieldNode, defaultValue):
defaultNode = getOrCreateChildElement(fieldNode,'default')
defaultNode.setContent(defaultValue)
def getOrCreatePLCHostNameField(self,configurationNode):
fieldNode = getOrCreateNamedFirstChild(configurationNode,'field','plcHostName')
descriptionNode = getOrCreateChildElement(fieldNode,'description')
......@@ -224,15 +255,14 @@ class FESADesignGenerator3_0_0(object):
array = getOrCreateChildElement(fieldNode,'array')
fillAttributes(array, {'type': 'char'})
dim = getOrCreateChildElement(array,'dim')
defaultNode = getOrCreateChildElement(fieldNode,'default')
defaultNode.setContent(plcClassVersion)
dim.setContent(str(len(defaultNode.getContent())))
self.addDefaultNode(fieldNode, plcClassVersion)
dim.setContent(str(len(plcClassVersion)))
return fieldNode
def getOrCreateRegisterValueItems(self,prop,block,isSetting):
def getOrCreateRegisterValueItems(self,prop,block,direction):
for register in block.getDesignRegisters():
if register.generateFesaValueItem:
self.getOrCreateValueItem(prop,register,isSetting)
self.getOrCreateValueItem(prop,register,direction)
def getOrCreateSettingProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating SettingProperty for Block: ' + block.name, {'debuglog': True})
......@@ -242,12 +272,23 @@ class FESADesignGenerator3_0_0(object):
else:
prop = getOrCreateNamedChildElement(parent,'setting-property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'multiplexed': 'false'})
self.getOrCreateRegisterValueItems(prop,block,True)
self.getOrCreateRegisterValueItems(prop,block,"INOUT")
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
self.getOrCreateAction(prop,block.fesaSetServerActionName,'set',actionsNode,'custom')
self.getOrCreateAction(prop,block.fesaGetServerActionName,'get',actionsNode,'custom')
return prop
def getOrCreateCommandProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating CommandProperty for Block: ' + block.name, {'debuglog': True})
if( hasChildren(parent)):
prop = getOrCreateNamedPreviousSiblingElement(parent,getFirstChild(parent), 'command-property',block.getFesaName())
else:
prop = getOrCreateNamedChildElement(parent,'command-property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'multiplexed': 'false'})
self.getOrCreateRegisterValueItems(prop,block,"IN")
self.getOrCreateAction(prop,block.fesaSetServerActionName,'set',actionsNode,'custom')
return prop
def getOrCreateAcquisitionProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating AcquisitionProperty for Block: ' + block.name, {'debuglog': True})
......@@ -257,7 +298,7 @@ class FESADesignGenerator3_0_0(object):
else:
prop = getOrCreateNamedChildElement(parent,'acquisition-property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'multiplexed': 'false', 'on-change': 'true'})
self.getOrCreateRegisterValueItems(prop,block,False)
self.getOrCreateRegisterValueItems(prop,block,"OUT")
self.getOrCreateAcqStampItem(prop)
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
......@@ -265,13 +306,15 @@ class FESADesignGenerator3_0_0(object):
self.getOrCreateAction(prop,block.fesaGetServerActionName,'get',actionsNode,'custom')
return prop
def getOrCreateGSISettingProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating GSISettingProperty for Block: ' + block.name, {'debuglog': True})
powerProp = parent.xpathEval('GSI-Power-Property')[0] # template is used --> there has to be a power prop
powerProps = parent.xpathEval('GSI-Power-Property')
if len(powerProps) == 0:
raise Exception("Error: A GSI-Power-Property needs to be available to generate a GSISettingProperty")
powerProp = powerProps[0] # template is used --> there has to be a power prop
prop = getOrCreateNamedPreviousSiblingElement(parent,powerProp, 'GSI-Setting-Property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'multiplexed': 'false'})
self.getOrCreateRegisterValueItems(prop,block,True)
self.getOrCreateRegisterValueItems(prop,block,"INOUT")
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
self.getOrCreateAction(prop,block.fesaSetServerActionName,'set',actionsNode,'custom')
......@@ -280,10 +323,12 @@ class FESADesignGenerator3_0_0(object):
def getOrCreateGSIAcquisitionProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating GSIAcquisitionProperty for Block: ' + block.name, {'debuglog': True})
versionProp = parent.xpathEval('GSI-Version-Property')[0] # template is used --> there has to be a version prop
prop = getOrCreateNamedPreviousSiblingElement(parent,versionProp, 'GSI-Acquisition-Property',block.getFesaName())
versionProps = parent.xpathEval('GSI-Version-Property')
if len(versionProps) == 0:
raise Exception("Error: A GSI-Version-Property needs to be available to generate a GSIAcquisitionProperty")
prop = getOrCreateNamedPreviousSiblingElement(parent,versionProps[0], 'GSI-Acquisition-Property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'multiplexed': 'false', 'on-change': 'true'})
self.getOrCreateRegisterValueItems(prop,block,False)
self.getOrCreateRegisterValueItems(prop,block,"OUT")
self.getOrCreateAcqStampItem(prop)
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
......@@ -295,17 +340,44 @@ class FESADesignGenerator3_0_0(object):
# propertyType only used during creation ! If named property already exists, it is just returned, no matter which type
def getOrCreateFESAProperty(self,parent,actionsNode,block):
if self.isGSITemplate(parent):
if parent.get_name() == 'setting':
return self.getOrCreateGSISettingProperty(parent,actionsNode,block)
if block.isSetting():
if block.getFesaName() == 'Power':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-Power-Property and connect silecs-fields manually")
else:
return self.getOrCreateGSISettingProperty(parent,actionsNode,block)
elif block.isCommand():
if block.getFesaName() == 'Init':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-Init-Property and connect silecs-fields manually")
elif block.getFesaName() == 'Reset':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-Reset-Property and connect silecs-fields manually")
else:
return self.getOrCreateCommandProperty(parent,actionsNode,block)
elif block.isAcquisition():
if block.getFesaName() == 'Status':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-Status-Property and connect silecs-fields manually")
elif block.getFesaName() == 'ModuleStatus':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-ModuleStatus-Property and connect silecs-fields manually")
elif block.getFesaName() == 'Version':
raise Exception("Error: Please use '@generateFesaProperty=false' for the GSI-Version-Property and connect silecs-fields manually")
else:
return self.getOrCreateGSIAcquisitionProperty(parent,actionsNode,block)
elif block.isConfiguration():
return self.getOrCreateGSIAcquisitionProperty(parent,actionsNode,block);
else:
return self.getOrCreateGSIAcquisitionProperty(parent,actionsNode,block)
raise Exception( "Cannot identify FESA GSI Property-type to use for block:" + block.name )
else:
if parent.get_name() == 'setting':
if block.isSetting():
return self.getOrCreateSettingProperty(parent,actionsNode,block)
else:
elif block.isCommand():
return self.getOrCreateCommandProperty(parent,actionsNode,block)
elif block.isAcquisition():
return self.getOrCreateAcquisitionProperty(parent,actionsNode,block)
elif block.isConfiguration():
return self.getOrCreateAcquisitionProperty(parent,actionsNode,block);
else:
raise Exception( "Cannot identify FESA Property-type to use for block:" + block.name )
def getOrCreateValueItem(self,propertyNode,register,isSetting):
def getOrCreateValueItem(self,propertyNode,register,direction):
iecommon.logDebug('Generating ValueItem for Register: ' + register.name, {'debuglog': True})
result = propertyNode.xpathEval("value-item[@name='" + register.getFesaFieldName() + "']")
if len(result):
......@@ -315,10 +387,7 @@ class FESADesignGenerator3_0_0(object):
valueItemNode = getOrCreateNamedPreviousSiblingElement(propertyNode,result[0],'value-item',register.getFesaFieldName())
else:
valueItemNode = getOrCreateNamedChildElement(propertyNode,'value-item',register.getFesaFieldName())
if isSetting:
fillAttributes(valueItemNode, {'direction': 'INOUT'})
else:
fillAttributes(valueItemNode, {'direction': 'OUT'})
fillAttributes(valueItemNode, {'direction': direction})
self.getOrCreateType(valueItemNode,register)
self.getOrCreateFieldRef(valueItemNode,register.getFesaFieldName())
......@@ -346,9 +415,10 @@ class FESADesignGenerator3_0_0(object):
elif reg.isAcquisition():
fieldNode = self.getOrCreateFieldNode(acquisitionNode,reg)
fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false'})
else: #volatile#
fieldNode = self.getOrCreateFieldNode(settingNode,reg)
fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'false'})
elif reg.isConfiguration():
fieldNode = self.getOrCreateFieldNode(configurationNode,reg)
else:
raise Exception( "Cannot identify register-type to use for register:" + reg.name )
self.getOrCreateType(fieldNode,reg)
globalDataNode = getOrCreateChildElement(dataNode,'global-data')
......@@ -377,32 +447,11 @@ class FESADesignGenerator3_0_0(object):
for block in designClass.getDesignBlocks():
if not block.generateFesaProperty:
continue #skip this block
if block.isWritable():
if block.isSetting() or block.isCommand():
propertyNode = self.getOrCreateFESAProperty(settingNode, actionsNode, block)
else:
propertyNode = self.getOrCreateFESAProperty(acquisitionNode,actionsNode,block)
#-------------------------------------------------------------------------
# Generates the scheduling-units node of the FESA design
# document parsing the SILECS class document
#-------------------------------------------------------------------------
def addDesignFileId(self,fesaDesignFile,logTopics):
nodeRequiringId = ['setting-property','acquisition-property','diagnostic-property',
'value-item','update-flag-item','cycle-name-item', 'acq-stamp-item',
'cycle-stamp-item','mode-item','host-item','port-item','config-item',
'state-item','fwk-topic-item','custom-topic-item','device-trace-item',
'bypass-action-item','diag-custom-topic','field','timing-event-source',
'timer-event-source','logical-event']
counter = 0
now = datetime.datetime.today()
id = '_' + now.strftime('%y%m%d%H%M%S') + '_%s'
for nodeName in nodeRequiringId:
for node in fesaDesignFile.xpathEval("//" + nodeName):
if node.hasProp("id"):
node.setProp("id", id%counter)
counter = counter +1
def fillXML(self,fesaVersion, className, fesaRoot, silecsRoot,logTopics={'errorlog': True}):
......@@ -428,7 +477,6 @@ class FESADesignGenerator3_0_0(object):
# Generate properties, Actions, Events, Scheduling Units
self.genDeviceInterface(designClass, fesaRoot,logTopics)
self.addDesignFileId(fesaRoot,logTopics)
return fesaRoot
#-------------------------------------------------------------------------
......
......@@ -24,7 +24,7 @@ import datetime
import socket
import iecommon
import fesaTemplates
import fesa.fesa_3_0_0.fesaTemplates as fesaTemplates
import iefiles
from iecommon import *
......@@ -47,25 +47,19 @@ def findBlockServerSetActionName(fesaRoot, propName):
def genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
designClass = DesignClass.getDesignClassFromRootNode(silecsRoot)
source = fesaTemplates.genHTop(className)
for block in designClass.getDesignBlocks():
if block.isWritable():
serverActionName = findBlockServerSetActionName(fesaRoot,block.getFesaName())
source += fesaTemplates.genHTopBlock(className, serverActionName)
source += fesaTemplates.genHTop2(className)
for block in designClass.getDesignBlocks():
for block in designClass.getDesignFesaBlocks():
if block.isAcquisition():
source += fesaTemplates.genHBlock('RO', block.name,block.getFesaName() )
elif block.isCommand():
source += fesaTemplates.genHBlock('WO', block.name,block.getFesaName())
source += fesaTemplates.genHReadBlock(className, block.name)
elif block.isCommand() or block.isConfiguration():
source += fesaTemplates.genHWriteBlock(className, block.name, block.getFesaName())
else: # Setting
source += fesaTemplates.genHBlock('RW', block.name,block.getFesaName())
source += fesaTemplates.genHReadWriteBlock(className, block.name, block.getFesaName())
source += fesaTemplates.genHBottom(className)
for block in designClass.getDesignBlocks():
for block in designClass.getDesignFesaBlocks():
source += fesaTemplates.genHDeclBlocks(block.name)
source += fesaTemplates.genHClosing(className)
......@@ -93,7 +87,8 @@ def genHSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
designClass = DesignClass.getDesignClassFromRootNode(silecsRoot)
finalSource = fesaTemplates.genCTop(className)
blockList = designClass.getDesignBlocks()
blockList = designClass.getDesignFesaBlocks()
for block in blockList:
finalSource += fesaTemplates.genCGlobal(className, block.name)
......@@ -103,24 +98,15 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCBlockConstr(block.name, className)
finalSource += fesaTemplates.genCPart2(className)
for block in blockList:
if (block.isWritable()):
# WARNING: In order to have multiplexed FESA fields, the corresponding SILECS registers' synchro mode must be 'NONE'
finalSource += fesaTemplates.genCSetPLC(className, block.name)
finalSource += fesaTemplates.genCPart3(className)
for block in blockList:
if (block.isReadable()):
# WARNING: In order to have multiplexed FESA fields, the corresponding SILECS registers' synchro mode must be 'NONE'
finalSource += fesaTemplates.genCGetPLC(className, block.name)
finalSource += fesaTemplates.updatePLCRegisters(className, blockList)
finalSource += fesaTemplates.updateFesaFields(className, blockList)
finalSource += fesaTemplates.genCPart4(className)
for block in blockList:
if block.isReadable():
finalSource += fesaTemplates.genCCommonGet(block.name,className)
if block.isSetting() or block.isAcquisition(): #configuration-fields in fesa are not writable, so no setter to generate for them !
finalSource += fesaTemplates.genCCommonGet(block.name, className)
finalSource += '\n'
finalSource += fesaTemplates.cRecv
for register in block.getDesignRegisters():
......@@ -136,10 +122,43 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCGetArrayReg(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCGetArray2DReg(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCGetCustomScalarReg(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCGetCustomArrayReg(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCGetCustomArray2DReg(register)
finalSource += '\n }\n'
if block.isSetting():
finalSource += fesaTemplates.genCDatatypeGet(block.name, block.getFesaName(), className)
finalSource += '\n'
finalSource += fesaTemplates.cRecv
for register in block.getDesignRegisters():
if register.valueType == 'string':
finalSource += fesaTemplates.genCGetStringRegData(register)
elif register.valueType == 'stringArray':
finalSource += fesaTemplates.genCGetStringArrayRegData(register)
elif register.valueType == 'stringArray2D':
iecommon.logError('ERROR: In register '+register.name+' - 2D array of strings not supported in FESA.', True, {'errorlog': True})
elif register.valueType == 'scalar':
finalSource += fesaTemplates.genCGetScalarRegData(register)
elif register.valueType == 'array':
finalSource += fesaTemplates.genCGetArrayRegData(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCGetArray2DRegData(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCGetCustomScalarRegData(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCGetCustomArrayRegData(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCGetCustomArray2DRegData(register)
finalSource += '\n }\n'
if block.isWritable():
finalSource += fesaTemplates.genCCommonSet(block.name,className)
finalSource += fesaTemplates.genCCommonSet(block.name, className)
for register in block.getDesignRegisters():
if register.valueType == 'string':
finalSource += fesaTemplates.genCSetStringReg(register)
......@@ -153,6 +172,12 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCSetArrayReg(register)
elif register.valueType == 'array2D':
finalSource += fesaTemplates.genCSetArray2DReg(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCSetScalarReg(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCSetCustomArrayReg(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCSetCustomArray2DReg(register)
finalSource += fesaTemplates.cSend
finalSource += ' }\n'
finalSource += fesaTemplates.genCDatatypeSet(block.name,block.getFesaName(), className)
......@@ -170,6 +195,12 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics):
finalSource += fesaTemplates.genCSetArrayRegData(register)
elif register.valueType == 'scalar':
finalSource += fesaTemplates.genCSetScalarRegData(register)
elif register.valueType == 'custom-type-scalar':
finalSource += fesaTemplates.genCSetScalarRegData(register)
elif register.valueType == 'custom-type-array':
finalSource += fesaTemplates.genCSetCustomArrayRegData(register)
elif register.valueType == 'custom-type-array2D':
finalSource += fesaTemplates.genCSetCustomArray2DRegData(register)
finalSource += fesaTemplates.cSend
finalSource += '\n }\n' # closing bracket for block
......
......@@ -16,11 +16,11 @@
import fesa.fesa_3_0_0.generateBuildEnvironment
def genMakefileClass(projectPath, centralMakefilePath, logTopics={'errorlog': True} ):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileClass(projectPath, centralMakefilePath, logTopics )
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileClass(projectPath, logTopics )
def genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileDU(projectPath, silecsBasePath, snap7BasePath, logTopics )
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genMakefileDU(projectPath, logTopics )
def genCProjectFile(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_0_0.generateBuildEnvironment.genCProjectFile(projectPath, logTopics )
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# This program is free software: you can redistribute it and/or modify
......@@ -13,19 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
PROJECT = silecs
PRODUCT = cli-client
VERSION = 0.0.0
import fesa.fillFesaDeployUnitBase
import fesa.fesa_3_0_0.fillFESADeployUnit
SKIP_MANIFEST = TRUE
#local
#COMMON_MAKE_PATH ?= /common/home/bel/schwinn/lnx/workspace-silecs-neon/generic-makefiles
#global
COMMON_MAKE_PATH ?= /opt/cern/buildsystem/generic/2.9.0
def fillDeployUnit(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
generator = fesa.fesa_3_0_0.fillFESADeployUnit.FESADeployUnitGenerator3_0_0() # identical with FESA 3.0.0
fesa.fillFesaDeployUnitBase.fillFesaDeployUnitBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
# product configuration
BIN_NAME = $(PROJECT)-$(PRODUCT)
DBG = false
# Include the generic make file
include $(COMMON_MAKE_PATH)/Make.generic
\ No newline at end of file
#!/usr/bin/python
# Copyright 2016 CERN and GSI
#
# This program is free software: you can redistribute it and/or modify
......@@ -13,28 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
PROJECT = silecs
PRODUCT = communication
VERSION = 0.0.0
import fesa.fesa_3_1_0.generateBuildEnvironment
SKIP_MANIFEST = TRUE
#local
#COMMON_MAKE_PATH ?= /common/home/bel/schwinn/lnx/workspace-silecs-neon/generic-makefiles
#global
COMMON_MAKE_PATH ?= /opt/cern/buildsystem/generic/2.9.0
def genMakefileClass(projectPath, logTopics={'errorlog': True} ):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileClass(projectPath, logTopics )
# product configuration
LIB_NAME = comm
DBG = true
def genMakefileDU(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_1_0.generateBuildEnvironment.genMakefileDU(projectPath, logTopics )
#COMPILER_FLAGS = -Os -fno-strict-aliasing -fexceptions -DLINUX -DARM_FIX -DDAVE_LITTLE_ENDIAN -D_GNU_SOURCE -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH)
COMPILER_FLAGS = -DMAJOR=$(MAJOR) -DMINOR=$(MINOR) -DPATCH=$(PATCH)
# Comment IN/Out to enable NI-Support
#COMPILER_FLAGS += -DNI_SUPPORT_ENABLED=TRUE
# Comment IN/Out to enable Modbus-Support
#COMPILER_FLAGS += -DMODBUS_SUPPORT_ENABLED=TRUE
# Include the generic make file
include $(COMMON_MAKE_PATH)/Make.generic
\ No newline at end of file
def genCProjectFile(projectPath, logTopics={'errorlog': True}):
return fesa.fesa_3_1_0.generateBuildEnvironment.genCProjectFile(projectPath, logTopics )
#!/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 fesa.fillFesaDesignBase
import fesa.fesa_3_1_0.generateFesaDesign
from iecommon import *
def fillDesignFile(fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics={'errorlog': True}):
generator = FESADesignGenerator7_3_0()
fesa.fillFesaDesignBase.fillDesignFileBase(generator,fesaVersion, className, workspacePath,fesaDesignXSDPath,logTopics)
class FESADesignGenerator7_3_0(fesa.fesa_3_1_0.generateFesaDesign.FESADesignGenerator3_1_0):
#overwrite 3_0_0 version (multiplexed --> cycle-bound)
def getOrCreateAcquisitionProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating AcquisitionProperty for Block: ' + block.name, {'debuglog': True})
prop = ""
if( hasChildren(parent)):
prop = getOrCreateNamedPreviousSiblingElement(parent,getFirstChild(parent), 'acquisition-property',block.getFesaName())
else:
prop = getOrCreateNamedChildElement(parent,'acquisition-property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'cycle-bound': 'false', 'on-change': 'true'})
self.getOrCreateRegisterValueItems(prop,block,"OUT")
self.getOrCreateAcqStampItem(prop)
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
self.getOrCreateCyleStampItem(prop)
self.getOrCreateAction(prop,block.fesaGetServerActionName,'get',actionsNode,'custom')
return prop
#overwrite 3_0_0 version (multiplexed --> cycle-bound)
def getOrCreateGSIAcquisitionProperty(self,parent,actionsNode,block):
iecommon.logDebug('Generating GSIAcquisitionProperty for Block: ' + block.name, {'debuglog': True})
versionProps = parent.xpathEval('GSI-Version-Property')
if len(versionProps) == 0:
raise Exception("Error: A GSI-Version-Property needs to be available to generate a GSIAcquisitionProperty")
prop = getOrCreateNamedPreviousSiblingElement(parent,versionProps[0], 'GSI-Acquisition-Property',block.getFesaName())
fillAttributes(prop, {'visibility': 'development', 'subscribable': 'true', 'cycle-bound': 'false', 'on-change': 'true'})
self.getOrCreateRegisterValueItems(prop,block,"OUT")
self.getOrCreateAcqStampItem(prop)
self.getOrCreateUpdateFlagItem(prop)
self.getOrCreateCyleNameItem(prop)
self.getOrCreateCyleStampItem(prop)
self.getOrCreateAction(prop,block.fesaGetServerActionName,'get',actionsNode,'custom')
self.getOrCreateAcquisitionContextItem(prop)
return prop
#overwrite 3_0_0 version (multiplexed --> cycle-bound for acquisition fileds)
def genData(self,designClass, doc,logTopics):
iecommon.logDebug("Creating data fields", logTopics)
dataNode = doc.xpathEval('/equipment-model/data')[0]
iecommon.logError("len(dataNode)" + dataNode.get_name(), logTopics)
deviceDataNode = getOrCreateChildElement(dataNode,'device-data')
configurationNode = getOrCreateChildElement(deviceDataNode,'configuration')
settingNode = getOrCreateChildElement(deviceDataNode,'setting')
acquisitionNode = getOrCreateChildElement(deviceDataNode,'acquisition')
self.getOrCreatePLCHostNameField(configurationNode)
self.getOrCreatePLCDeviceLabelField(configurationNode)
for block in designClass.getDesignBlocks():
for reg in block.getDesignRegisters():
if reg.isSetting():
fieldNode = self.getOrCreateFieldNode(settingNode,reg)
fillAttributes(fieldNode, {'multiplexed': 'false', 'persistent': 'true'})
elif reg.isAcquisition():
fieldNode = self.getOrCreateFieldNode(acquisitionNode,reg)
fillAttributes(fieldNode, {'cycle-bound': 'false', 'persistent': 'false'})
elif reg.isConfiguration():
fieldNode = self.getOrCreateFieldNode(configurationNode,reg)
else:
raise Exception( "Cannot identify register-type to use for register:" + reg.name )
self.getOrCreateType(fieldNode,reg)
globalDataNode = getOrCreateChildElement(dataNode,'global-data')
globalConfigurationNode = ""
if len(globalDataNode.xpathEval("configuration")) == 0:
if len( globalDataNode.xpathEval("*")) == 0:
globalConfigurationNode = getOrCreateChildElement(globalDataNode,'configuration')
else:
globalConfigurationNode = getOrCreatePreviousSiblingElement(getFirstChild(globalDataNode),'configuration')
else:
globalConfigurationNode = globalDataNode.xpathEval("configuration")[0]
self.getOrCreatePLCClassVersionField(globalConfigurationNode,designClass.version)
# Fill custom-types with enums.
enums = designClass.getEnums()
customTypesNode = doc.xpathEval('/equipment-model/custom-types')[0]
for enum in enums:
enumElement = getOrCreateNamedChildElement(customTypesNode, "enum", enum.name)
existing_items = enumElement.xpathEval("item")
to_add = []
to_edit = []
# Loop through all new enums and check which should be added and which edited.
for item in enum.items:
if item.symbol in [item.prop("symbol") for item in existing_items]:
to_edit.append(item)
else:
to_add.append(item)
# Loop though all existing enums and remove any which are not in new enums.
to_add_edit = to_add + to_edit
for existing in existing_items:
if existing.prop("symbol") not in [item.symbol for item in to_add_edit]:
existing.unlinkNode()
existing.freeNode()
# Edit existing items.
for item in to_edit:
for existing in existing_items:
if existing.prop("symbol") != item.symbol:
continue
existing.setProp("access", item.access)
existing.setProp("value", item.value)
# Add missing items.
for item in to_add:
itemElement = libxml2.newNode("item")
enumElement.addChild(itemElement)
itemElement.setProp("access", item.access)
itemElement.setProp("value", item.value)
itemElement.setProp("symbol", item.symbol)