--- a/ConfigTreeNode.py Thu Nov 15 22:57:55 2012 +0100
+++ b/ConfigTreeNode.py Thu Nov 15 23:00:53 2012 +0100
@@ -195,6 +195,18 @@
shutil.copytree(src_CTNPath, self.CTNPath)
return True
+ def CTNGlobalInstances(self):
+ """
+ @return: [(instance_name, instance_type),...]
+ """
+ return []
+
+ def _GlobalInstances(self):
+ instances = self.CTNGlobalInstances()
+ for CTNChild in self.IECSortedChildren():
+ instances.extend(CTNChild._GlobalInstances())
+ return instances
+
def CTNGenerate_C(self, buildpath, locations):
"""
Generate C code
--- a/PLCControler.py Thu Nov 15 22:57:55 2012 +0100
+++ b/PLCControler.py Thu Nov 15 23:00:53 2012 +0100
@@ -1476,6 +1476,32 @@
def GetVariableLocationTree(self):
return []
+ def GetConfNodeGlobalInstances(self):
+ return []
+
+ def GetConfigurationExtraVariables(self):
+ global_vars = []
+ for var_name, var_type in self.GetConfNodeGlobalInstances():
+ tempvar = plcopen.varListPlain_variable()
+ tempvar.setname(var_name)
+
+ tempvartype = plcopen.dataType()
+ if var_type in self.GetBaseTypes():
+ if var_type == "STRING":
+ var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
+ elif var_type == "WSTRING":
+ var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
+ else:
+ var_type.setcontent({"name" : var_type, "value" : None})
+ else:
+ tempderivedtype = plcopen.derivedTypes_derived()
+ tempderivedtype.setname(var_type)
+ tempvartype.setcontent({"name" : "derived", "value" : tempderivedtype})
+ tempvar.settype(tempvartype)
+
+ global_vars.append(tempvar)
+ return global_vars
+
# Function that returns the block definition associated to the block type given
def GetBlockType(self, type, inputs = None, debug = False):
result_blocktype = None
@@ -1723,6 +1749,8 @@
if words[0] == "D":
infos = {}
datatype = project.getdataType(words[1])
+ if datatype is None:
+ return None
basetype_content = datatype.baseType.getcontent()
if basetype_content["value"] is None or basetype_content["name"] in ["string", "wstring"]:
infos["type"] = "Directly"
--- a/PLCGenerator.py Thu Nov 15 22:57:55 2012 +0100
+++ b/PLCGenerator.py Thu Nov 15 23:00:53 2012 +0100
@@ -268,8 +268,17 @@
(configuration.getname(), (tagname, "name")),
("\n", ())]
var_number = 0
+
+ varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
+
+ extra_variables = self.Controler.GetConfigurationExtraVariables()
+ if len(extra_variables) > 0:
+ if len(varlists) == 0:
+ varlists = [(plcopen.interface_globalVars(), [])]
+ varlists[-1][1].extend(extra_variables)
+
# Generate any global variable in configuration
- for varlist in configuration.getglobalVars():
+ for varlist, varlist_variables in varlists:
variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
# Generate variable block with modifier
config += [(" VAR_GLOBAL", ())]
@@ -281,7 +290,7 @@
config += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
config += [("\n", ())]
# Generate any variable of this block
- for var in varlist.getvariable():
+ for var in varlist_variables:
vartype_content = var.gettype().getcontent()
if vartype_content["name"] == "derived":
var_type = vartype_content["value"].getname()
@@ -512,15 +521,24 @@
current_type = var_type
break
while current_type is not None and len(parts) > 0:
- tagname = self.ParentGenerator.Controler.ComputeDataTypeName(current_type)
- infos = self.ParentGenerator.Controler.GetDataTypeInfos(tagname)
- name = parts.pop(0)
- current_type = None
- if infos is not None and infos["type"] == "Structure":
- for element in infos["elements"]:
- if element["Name"] == name:
- current_type = element["Type"]
+ blocktype = self.ParentGenerator.Controler.GetBlockType(current_type)
+ if blocktype is not None:
+ name = parts.pop(0)
+ current_type = None
+ for var_name, var_type, var_modifier in blocktype["inputs"] + blocktype["outputs"]:
+ if var_name == name:
+ current_type = var_type
break
+ else:
+ tagname = self.ParentGenerator.Controler.ComputeDataTypeName(current_type)
+ infos = self.ParentGenerator.Controler.GetDataTypeInfos(tagname)
+ if infos is not None and infos["type"] == "Structure":
+ name = parts.pop(0)
+ current_type = None
+ for element in infos["elements"]:
+ if element["Name"] == name:
+ current_type = element["Type"]
+ break
return current_type
# Return connectors linked by a connection to the given connector
--- a/ProjectController.py Thu Nov 15 22:57:55 2012 +0100
+++ b/ProjectController.py Thu Nov 15 23:00:53 2012 +0100
@@ -503,7 +503,10 @@
# finally store into located variable list
locations.append(resdict)
return locations
-
+
+ def GetConfNodeGlobalInstances(self):
+ return self._GlobalInstances()
+
def _Generate_SoftPLC(self):
"""
Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C
@@ -697,15 +700,23 @@
self._ProgramList.append(attrs)
# second section contains all variables
+ config_FBs = {}
for line in ListGroup[1]:
# Split and Maps each field to dictionnary entries
attrs = dict(zip(VariablesListAttributeName,line.strip().split(';')))
# Truncate "C_path" to remove conf an ressources names
parts = attrs["C_path"].split(".",2)
if len(parts) > 2:
- attrs["C_path"] = '__'.join(parts[1:])
+ config_FB = config_FBs.get(tuple(parts[:2]))
+ if config_FB:
+ parts = [config_FB] + parts[2:]
+ attrs["C_path"] = '.'.join(parts)
+ else:
+ attrs["C_path"] = '__'.join(parts[1:])
else:
attrs["C_path"] = '__'.join(parts)
+ if attrs["vartype"] == "FB":
+ config_FBs[tuple(parts)] = attrs["C_path"]
# Push this dictionnary into result.
self._VariablesList.append(attrs)
# Fill in IEC<->C translation dicts
@@ -741,18 +752,19 @@
"IN":"extern __IEC_%(type)s_p %(C_path)s;",
"MEM":"extern __IEC_%(type)s_p %(C_path)s;",
"OUT":"extern __IEC_%(type)s_p %(C_path)s;",
- "VAR":"extern __IEC_%(type)s_t %(C_path)s;"}[v["vartype"]]%v
- for v in self._VariablesList if v["vartype"] != "FB" and v["C_path"].find('.')<0]),
+ "VAR":"extern __IEC_%(type)s_t %(C_path)s;",
+ "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v
+ for v in self._VariablesList if v["C_path"].find('.')<0]),
"for_each_variable_do_code":"\n".join([
- {"EXT":" (*fp)((void*)&%(C_path)s,%(type)s_P_ENUM);\n",
- "IN":" (*fp)((void*)&%(C_path)s,%(type)s_P_ENUM);\n",
- "MEM":" (*fp)((void*)&%(C_path)s,%(type)s_O_ENUM);\n",
- "OUT":" (*fp)((void*)&%(C_path)s,%(type)s_O_ENUM);\n",
- "VAR":" (*fp)((void*)&%(C_path)s,%(type)s_ENUM);\n"}[v["vartype"]]%v
+ {"EXT":" (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
+ "IN":" (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n",
+ "MEM":" (*fp)((void*)&(%(C_path)s),%(type)s_O_ENUM);\n",
+ "OUT":" (*fp)((void*)&(%(C_path)s),%(type)s_O_ENUM);\n",
+ "VAR":" (*fp)((void*)&(%(C_path)s),%(type)s_ENUM);\n"}[v["vartype"]]%v
for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ]),
"find_variable_case_code":"\n".join([
" case %(num)s:\n"%v+
- " *varp = (void*)&%(C_path)s;\n"%v+
+ " *varp = (void*)&(%(C_path)s);\n"%v+
{"EXT":" return %(type)s_P_ENUM;\n",
"IN":" return %(type)s_P_ENUM;\n",
"MEM":" return %(type)s_O_ENUM;\n",