# HG changeset patch # User etisserant # Date 1214236341 -7200 # Node ID 482ca562d414019981963115cd98f55d847a25f8 # Parent bf3eac08a96bf345f98ac71f1ee6aaacf23d6629 Support for extern pointer for located variables + Preliminary slave code (broken) diff -r bf3eac08a96b -r 482ca562d414 plugins/canfestival/canfestival.py --- a/plugins/canfestival/canfestival.py Mon Jun 23 16:06:20 2008 +0200 +++ b/plugins/canfestival/canfestival.py Mon Jun 23 17:52:21 2008 +0200 @@ -1,4 +1,4 @@ -import os, sys, wx +import os, sys base_folder = os.path.split(sys.path[0])[0] CanFestivalPath = os.path.join(base_folder, "CanFestival-3") sys.path.append(os.path.join(CanFestivalPath, "objdictgen")) @@ -15,14 +15,18 @@ from gnosis.xml.pickle.util import setParanoia setParanoia(0) -class _NetworkEdit(networkedit): - " Overload some of CanFestival Network Editor methods " +#-------------------------------------------------- +# SLAVE +#-------------------------------------------------- + +class _NodeEdit(objdictedit): + " Overload some of CanFestival Node Editor methods " def OnCloseFrame(self, event): " Do reset _NodeListPlug.View when closed" self._onclose() event.Skip() -class _NodeListPlug(NodeList): +class _SlavePlug(NodeManager): XSD = """ @@ -30,18 +34,30 @@ - """ + def GetSlaveODPath(self): + os.path.join(self.PlugPath(), 'slave.od') + def __init__(self): - manager = NodeManager() # TODO change netname when name change - NodeList.__init__(self, manager, self.BaseParams.getName()) - self.LoadProject(self.PlugPath()) - + NodeManager.__init__(self) + odfilepath = self.GetSlaveODPath() + if(os.path.isfile(odfilepath)): + self.OpenFileInCurrent(odfilepath) + else: + self.CreateNewNode("SlaveNode", # Name - will be changed at build time + 0x00, # NodeID - will be changed at build time + "slave", # Type + "", # description + "None", # profile + "", # prfile filepath + "heartbeat", # NMT + []) # options + _View = None def _OpenView(self, logger): if not self._View: @@ -49,7 +65,7 @@ self._View = None def _onsave(): self.GetPlugRoot().SaveProject() - self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self) + self._View = _NodeEdit(self.GetPlugRoot().AppFrame, self) # TODO redefine BusId when IEC channel change self._View.SetBusId(self.GetCurrentLocation()) self._View._onclose = _onclose @@ -121,6 +137,117 @@ file.close() return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False + +#-------------------------------------------------- +# MASTER +#-------------------------------------------------- + +class _NetworkEdit(networkedit): + " Overload some of CanFestival Network Editor methods " + def OnCloseFrame(self, event): + " Do reset _NodeListPlug.View when closed" + self._onclose() + event.Skip() + +class _NodeListPlug(NodeList): + XSD = """ + + + + + + + + + + + """ + + def __init__(self): + manager = NodeManager() + # TODO change netname when name change + NodeList.__init__(self, manager, self.BaseParams.getName()) + self.LoadProject(self.PlugPath()) + + _View = None + def _OpenView(self, logger): + if not self._View: + def _onclose(): + self._View = None + def _onsave(): + self.GetPlugRoot().SaveProject() + self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self) + # TODO redefine BusId when IEC channel change + self._View.SetBusId(self.GetCurrentLocation()) + self._View._onclose = _onclose + self._View._onsave = _onsave + self._View.Show() + + def _ShowMasterGenerated(self, logger): + buildpath = self._getBuildPath() + # Eventually create build dir + if not os.path.exists(buildpath): + logger.write_error("Error: No PLC built\n") + return + + masterpath = os.path.join(buildpath, "MasterGenerated.od") + if not os.path.exists(masterpath): + logger.write_error("Error: No Master generated\n") + return + + new_dialog = objdictedit(None, [masterpath]) + new_dialog.Show() + + PluginMethods = [ + {"bitmap" : os.path.join("images", "NetworkEdit"), + "name" : "Edit network", + "tooltip" : "Edit CanOpen Network with NetworkEdit", + "method" : "_OpenView"}, + {"name" : "Show Master", + "tooltip" : "Show Master generated by config_utils", + "method" : "_ShowMasterGenerated"} + ] + + def OnPlugClose(self): + if self._View: + self._View.Close() + + def PlugTestModified(self): + return self.ChangesToSave or self.HasChanged() + + def OnPlugSave(self): + self.SetRoot(self.PlugPath()) + self.SaveProject() + return True + + def PlugGenerate_C(self, buildpath, locations, logger): + """ + Generate C code + @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) + @param locations: List of complete variables locations \ + [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...) + "NAME" : name of the variable (generally "__IW0_1_2" style) + "DIR" : direction "Q","I" or "M" + "SIZE" : size "X", "B", "W", "D", "L" + "LOC" : tuple of interger for IEC location (0,1,2,...) + }, ...] + @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND + """ + current_location = self.GetCurrentLocation() + # define a unique name for the generated C file + prefix = "_".join(map(lambda x:str(x), current_location)) + Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) + # Create a new copy of the model with DCF loaded with PDO mappings for desired location + master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix) + res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers) + if res : + raise Exception, res + + file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") + dump(master, file) + file.close() + + return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False class RootClass: XSD = """ @@ -133,11 +260,11 @@ """ - PlugChildsTypes = [("CanOpenNode",_NodeListPlug, "CanOpen node")] + PlugChildsTypes = [("CanOpenNode",_NodeListPlug, "CanOpen Master"),("CanOpenSlave",_SlavePlug, "CanOpen Slave")] def GetParamsAttributes(self, path = None): infos = PlugTemplate.GetParamsAttributes(self, path = None) for element in infos: - if element["name"] == "CanFestivalInstance": + if element["name"] == "CanFestivalInstance": for child in element["children"]: if child["name"] == "CAN_Driver": DLL_LIST= getattr(canfestival_config,"DLL_LIST",None) @@ -178,7 +305,7 @@ format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n '%(nodename) format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n '%(nodename) - if wx.Platform == '__WXMSW__': + if sys.platform == 'win32': if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))): format_dict["candriver"] += '_DEBUG.dll' else: diff -r bf3eac08a96b -r 482ca562d414 plugins/canfestival/config_utils.py --- a/plugins/canfestival/config_utils.py Mon Jun 23 16:06:20 2008 +0200 +++ b/plugins/canfestival/config_utils.py Mon Jun 23 17:52:21 2008 +0200 @@ -138,6 +138,8 @@ self.SlavesPdoNumber = {} # Dictionary of mapping value where unexpected variables are stored self.TrashVariables = {} + # Dictionary of pointed variables + self.PointedVariables = {} self.NodeList = nodelist self.Manager = self.NodeList.Manager @@ -145,6 +147,8 @@ self.MasterNode.SetNodeName(nodename) self.PrepareMasterNode() + def GetPointedVariables(self): + return self.PointedVariables def RemoveUsedNodeCobId(self, node): """ @@ -515,17 +519,18 @@ VariableTypeOffset[variable_infos["sizelocation"]] * VariableIncrement + \ variable_infos["nodeid"] + # Generate entry name + indexname = "%s%s%s_%d"%(VariableDirText[variable_infos["pdotype"]], + variable_infos["sizelocation"], + '_'.join(map(str,current_location)), + variable_infos["nodeid"]) + # Search for an entry that has an empty subindex while mapvariableidx < VariableStartIndex[variable_infos["pdotype"]] + 0x2000: # Entry doesn't exist if not self.MasterNode.IsEntry(mapvariableidx): - # Generate entry name - indexname = "%s%s%s_%d"%(VariableDirText[variable_infos["pdotype"]], - variable_infos["sizelocation"], - '_'.join(map(str,current_location)), - variable_infos["nodeid"]) # Add entry to MasterNode - self.Manager.AddMapVariableToCurrent(mapvariableidx, indexname, 3, 1, self.MasterNode) + self.Manager.AddMapVariableToCurrent(mapvariableidx, "beremiz"+indexname, 3, 1, self.MasterNode) new_index = True nbsubentries = self.MasterNode.GetEntry(mapvariableidx, 0x00) else: @@ -557,6 +562,9 @@ if typeinfos != None: value = (mapvariableidx << 16) + ((nbsubentries) << 8) + typeinfos["size"] self.MasterNode.SetEntry(current_idx + 0x200, subindex, value) + + # Add variable to pointed variables + self.PointedVariables[(mapvariableidx, nbsubentries)] = "%s_%s"%(indexname, subindexname) def GenerateConciseDCF(locations, current_location, nodelist, sync_TPDOs, nodename): """ @@ -574,7 +582,7 @@ dcfgenerator = ConciseDCFGenerator(nodelist, nodename) dcfgenerator.GenerateDCF(locations, current_location, sync_TPDOs) - return dcfgenerator.GetMasterNode() + return dcfgenerator.GetMasterNode(), dcfgenerator.GetPointedVariables() if __name__ == "__main__": import os, sys, getopt