etisserant@20: import os, sys
etisserant@20: base_folder = os.path.split(sys.path[0])[0]
etisserant@49: CanFestivalPath = os.path.join(base_folder, "CanFestival-3")
etisserant@49: sys.path.append(os.path.join(CanFestivalPath, "objdictgen"))
etisserant@20:
lbessard@11: from nodelist import NodeList
lbessard@11: from nodemanager import NodeManager
lbessard@11: import config_utils, gen_cfile
etisserant@12: from networkedit import networkedit
lbessard@77: from objdictedit import objdictedit
etisserant@49: import canfestival_config
greg@95: from plugger import PlugTemplate
lbessard@11:
lbessard@77: from gnosis.xml.pickle import *
lbessard@77: from gnosis.xml.pickle.util import setParanoia
lbessard@77: setParanoia(0)
lbessard@77:
etisserant@13: class _NetworkEdit(networkedit):
etisserant@13: " Overload some of CanFestival Network Editor methods "
etisserant@12: def OnCloseFrame(self, event):
etisserant@13: " Do reset _NodeListPlug.View when closed"
etisserant@13: self._onclose()
etisserant@12: event.Skip()
etisserant@12:
etisserant@13: class _NodeListPlug(NodeList):
etisserant@12: XSD = """
etisserant@12:
etisserant@12:
etisserant@12:
lbessard@86:
lbessard@86:
lbessard@86:
lbessard@86:
etisserant@12:
etisserant@12:
etisserant@12:
etisserant@12: """
etisserant@12:
lbessard@17: def __init__(self):
lbessard@11: manager = NodeManager()
etisserant@23: # TODO change netname when name change
etisserant@23: NodeList.__init__(self, manager, self.BaseParams.getName())
lbessard@17: self.LoadProject(self.PlugPath())
lbessard@11:
etisserant@13: _View = None
etisserant@18: def _OpenView(self, logger):
etisserant@13: if not self._View:
etisserant@13: def _onclose():
etisserant@30: self._View = None
lbessard@25: def _onsave():
lbessard@25: self.GetPlugRoot().SaveProject()
etisserant@23: self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self)
etisserant@23: # TODO redefine BusId when IEC channel change
etisserant@23: self._View.SetBusId(self.GetCurrentLocation())
etisserant@13: self._View._onclose = _onclose
lbessard@25: self._View._onsave = _onsave
etisserant@23: self._View.Show()
etisserant@23:
lbessard@77: def _ShowMasterGenerated(self, logger):
lbessard@77: buildpath = self._getBuildPath()
lbessard@77: # Eventually create build dir
lbessard@77: if not os.path.exists(buildpath):
lbessard@77: logger.write_error("Error: No PLC built\n")
lbessard@77: return
lbessard@77:
lbessard@77: masterpath = os.path.join(buildpath, "MasterGenerated.od")
lbessard@77: if not os.path.exists(masterpath):
lbessard@77: logger.write_error("Error: No Master generated\n")
lbessard@77: return
lbessard@77:
lbessard@77: new_dialog = objdictedit(None, [masterpath])
lbessard@77: new_dialog.Show()
lbessard@77:
lbessard@65: PluginMethods = [
lbessard@82: {"bitmap" : os.path.join("images", "NetworkEdit"),
lbessard@65: "name" : "Edit network",
lbessard@65: "tooltip" : "Edit CanOpen Network with NetworkEdit",
etisserant@105: "method" : "_OpenView"},
lbessard@77: {"name" : "Show Master",
lbessard@77: "tooltip" : "Show Master generated by config_utils",
etisserant@105: "method" : "_ShowMasterGenerated"}
lbessard@65: ]
etisserant@13:
etisserant@13: def OnPlugClose(self):
etisserant@13: if self._View:
etisserant@13: self._View.Close()
etisserant@13:
etisserant@13: def PlugTestModified(self):
etisserant@118: return self.ChangesToSave or self.HasChanged()
etisserant@12:
lbessard@17: def OnPlugSave(self):
etisserant@32: self.SetRoot(self.PlugPath())
lbessard@11: self.SaveProject()
etisserant@12: return True
etisserant@12:
etisserant@24: def PlugGenerate_C(self, buildpath, locations, logger):
etisserant@12: """
etisserant@15: Generate C code
etisserant@15: @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
etisserant@15: @param locations: List of complete variables locations \
etisserant@22: [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
etisserant@22: "NAME" : name of the variable (generally "__IW0_1_2" style)
etisserant@22: "DIR" : direction "Q","I" or "M"
etisserant@22: "SIZE" : size "X", "B", "W", "D", "L"
etisserant@22: "LOC" : tuple of interger for IEC location (0,1,2,...)
etisserant@22: }, ...]
etisserant@22: @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
etisserant@12: """
etisserant@24: current_location = self.GetCurrentLocation()
etisserant@22: # define a unique name for the generated C file
etisserant@15: prefix = "_".join(map(lambda x:str(x), current_location))
etisserant@49: Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix )
etisserant@22: # Create a new copy of the model with DCF loaded with PDO mappings for desired location
etisserant@57: master = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix)
etisserant@15: res = gen_cfile.GenerateFile(Gen_OD_path, master)
etisserant@15: if res :
etisserant@15: raise Exception, res
etisserant@15:
lbessard@77: file = open(os.path.join(buildpath, "MasterGenerated.od"), "w")
lbessard@77: dump(master, file)
lbessard@77: file.close()
lbessard@77:
etisserant@52: return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False
etisserant@12:
etisserant@13: class RootClass:
etisserant@12: XSD = """
etisserant@12:
etisserant@12:
etisserant@12:
lbessard@86:
etisserant@12:
etisserant@12:
etisserant@12:
etisserant@12: """
etisserant@106: PlugChildsTypes = [("CanOpenNode",_NodeListPlug, "CanOpen node")]
greg@95: def GetParamsAttributes(self, path = None):
greg@95: infos = PlugTemplate.GetParamsAttributes(self, path = None)
greg@95: for element in infos:
greg@95: if element["name"] == "CanFestivalInstance":
greg@95: for child in element["children"]:
greg@95: if child["name"] == "CAN_Driver":
greg@95: DLL_LIST= getattr(canfestival_config,"DLL_LIST",None)
greg@95: if DLL_LIST is not None:
greg@95: child["type"] = DLL_LIST
greg@95: return infos
greg@95: return infos
lbessard@11:
etisserant@24: def PlugGenerate_C(self, buildpath, locations, logger):
etisserant@52:
etisserant@52: format_dict = {"locstr" : "_".join(map(str,self.GetCurrentLocation())),
etisserant@52: "candriver" : self.CanFestivalInstance.getCAN_Driver(),
etisserant@52: "nodes_includes" : "",
etisserant@52: "board_decls" : "",
etisserant@59: "nodes_declare" : "",
etisserant@52: "nodes_init" : "",
etisserant@52: "nodes_open" : "",
etisserant@57: "nodes_close" : "",
etisserant@57: "nodes_send_sync" : "",
etisserant@57: "nodes_proceed_sync" : ""}
etisserant@52: for child in self.IECSortedChilds():
etisserant@52: childlocstr = "_".join(map(str,child.GetCurrentLocation()))
etisserant@52: nodename = "OD_%s" % childlocstr
etisserant@52:
etisserant@52: format_dict["nodes_includes"] += '#include "%s.h"\n'%(nodename)
etisserant@52: format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n'%(
etisserant@52: nodename,
etisserant@52: child.CanFestivalNode.getCAN_Device(),
etisserant@52: child.CanFestivalNode.getCAN_Baudrate())
etisserant@59: format_dict["nodes_declare"] += 'NODE_DECLARE(%s, %s)\n '%(
etisserant@59: nodename,
etisserant@59: child.CanFestivalNode.getNodeId())
etisserant@57: format_dict["nodes_init"] += 'NODE_INIT(%s, %s)\n '%(
etisserant@52: nodename,
etisserant@52: child.CanFestivalNode.getNodeId())
etisserant@57: format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename)
etisserant@57: format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename)
etisserant@57: format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n '%(nodename)
etisserant@57: format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n '%(nodename)
etisserant@52: filename = os.path.join(os.path.split(__file__)[0],"cf_runtime.c")
etisserant@52: cf_main = open(filename).read() % format_dict
etisserant@52: cf_main_path = os.path.join(buildpath, "CF_%(locstr)s.c"%format_dict)
etisserant@52: f = open(cf_main_path,'w')
etisserant@52: f.write(cf_main)
etisserant@52: f.close()
etisserant@52:
etisserant@52: return [(cf_main_path, canfestival_config.getCFLAGS(CanFestivalPath))],canfestival_config.getLDFLAGS(CanFestivalPath), True
lbessard@11:
etisserant@15: