# HG changeset patch # User Laurent Bessard # Date 1348435557 -7200 # Node ID 49242019a9ca9a82948ec90bc5c9248d4d105eb2 # Parent 7d0ebbff1d083345702aa18bc42486b6bf7d4190 Fix C code Generator to use CoE section contained in the slave ESI file for defining Ethercat network configuration diff -r 7d0ebbff1d08 -r 49242019a9ca etherlab/etherlab.py --- a/etherlab/etherlab.py Sat Sep 22 12:07:06 2012 +0200 +++ b/etherlab/etherlab.py Sun Sep 23 23:25:57 2012 +0200 @@ -61,16 +61,6 @@ class _EthercatSlaveCTN: - XSD = """ - - - - - - - - """ - NODE_PROFILE = None EditorType = NodeEditor @@ -184,7 +174,6 @@ - %s @@ -361,7 +350,6 @@ - @@ -655,13 +643,8 @@ slaves = self.GetSlaves() for slave_pos in slaves: slave = self.GetSlave(slave_pos) - slave_node = self.GetChildByIECLocation([slave_pos]) - if slave_node.CTNParams is not None: - slave_infos = slave_node.CTNParams[1] - else: - slave_infos = None if slave is not None: - self.FileGenerator.DeclareSlave(slave_pos, slave.getInfo().getAutoIncAddr(), slave.getType(), slave_infos) + self.FileGenerator.DeclareSlave(slave_pos, slave.getInfo().getAutoIncAddr(), slave.getType()) for location in locations: loc = location["LOC"][len(current_location):] @@ -821,9 +804,9 @@ def __del__(self): self.Controler = None - - def DeclareSlave(self, slave_index, slave_alias, slave, slave_infos): - self.Slaves.append((slave_index, slave_alias, slave, slave_infos)) + + def DeclareSlave(self, slave_index, slave_alias, slave): + self.Slaves.append((slave_index, slave_alias, slave)) def DeclareVariable(self, slave_index, index, subindex, iec_type, dir, name): slave_variables = self.UsedVariables.setdefault(slave_index, {}) @@ -838,14 +821,15 @@ def GenerateCFile(self, filepath, location_str, etherlab_node_infos): + # Extract etherlab master code template plc_etherlab_filepath = os.path.join(os.path.split(__file__)[0], "plc_etherlab.c") plc_etherlab_file = open(plc_etherlab_filepath, 'r') plc_etherlab_code = plc_etherlab_file.read() plc_etherlab_file.close() + # Initialize strings for formatting master code template str_completion = { "location": location_str, - "configure_pdos": int(etherlab_node_infos.getConfigurePDOs()), "master_number": etherlab_node_infos.getMasterNumber(), "located_variables_declaration": [], "used_pdo_entry_offset_variables_declaration": [], @@ -859,35 +843,48 @@ "publish_variables": [], } + # Initialize variable storing variable mapping state for slave_entries in self.UsedVariables.itervalues(): for entry_infos in slave_entries.itervalues(): entry_infos["mapped"] = False + # Sort slaves by position (IEC_Channel) self.Slaves.sort() + # Initialize dictionary storing alias auto-increment position values alias = {} - for (slave_idx, slave_alias, type_infos, slave_infos) in self.Slaves: + + # Generating code for each slave + for (slave_idx, slave_alias, type_infos) in self.Slaves: + + # Defining slave alias and auto-increment position if alias.get(slave_alias) is not None: alias[slave_alias] += 1 else: alias[slave_alias] = 0 slave_pos = (slave_alias, alias[slave_alias]) + # Extract slave device informations device = self.Controler.GetModuleInfos(type_infos) if device is not None: - + + # Extract slaves variables to be mapped slave_variables = self.UsedVariables.get(slave_idx, {}) + + # Extract slave device object dictionary entries device_entries = device.GetEntriesList() - if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0: + # Adding code for declaring slave in master code template strings + for element in ["vendor", "product_code", "revision_number"]: + type_infos[element] = ExtractHexDecValue(type_infos[element]) + type_infos.update(dict(zip(["slave", "alias", "position"], (slave_idx,) + slave_pos))) + + # Extract slave device CoE informations + device_coe = device.getCoE() + if device_coe is not None: - for element in ["vendor", "product_code", "revision_number"]: - type_infos[element] = ExtractHexDecValue(type_infos[element]) - type_infos.update(dict(zip(["slave", "alias", "position"], (slave_idx,) + slave_pos))) - - str_completion["slaves_declaration"] += "static ec_slave_config_t *slave%(slave)d = NULL;\n" % type_infos - str_completion["slaves_configuration"] += SLAVE_CONFIGURATION_TEMPLATE % type_infos - - for initCmd in device.getInitCmd(): + # If device support CanOpen over Ethernet, adding code for calling + # init commands when initializing slave in master code template strings + for initCmd in device_coe.getInitCmd(): index = ExtractHexDecValue(initCmd.getIndex()) subindex = ExtractHexDecValue(initCmd.getSubIndex()) entry = device_entries.get((index, subindex), None) @@ -903,7 +900,20 @@ } init_cmd_infos.update(type_infos) str_completion["slaves_initialization"] += SLAVE_INITIALIZATION_TEMPLATE % init_cmd_infos - + + # Extract slave device PDO configuration capabilities + PdoAssign = device_coe.getPdoAssign() + PdoConfig = device_coe.getPdoConfig() + else: + PdoAssign = PdoConfig = False + + # Test if slave has a configuration or need one + if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0 and PdoConfig and PdoAssign: + + str_completion["slaves_declaration"] += "static ec_slave_config_t *slave%(slave)d = NULL;\n" % type_infos + str_completion["slaves_configuration"] += SLAVE_CONFIGURATION_TEMPLATE % type_infos + + # Initializing pdos_infos = { "pdos_entries_infos": [], "pdos_infos": [], @@ -989,7 +999,7 @@ ConfigureVariable(entry_infos, str_completion) - elif pdo_type == "Outputs" and entry.getDataType() is not None: + elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None: entry_infos["dir"] = "Q" entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8) entry_infos["var_type"] = entry.getDataType().getcontent() @@ -1024,7 +1034,7 @@ "entries_number": len(entries_infos), "fixed": pdo.getFixed() == True}) - if slave_infos is None or slave_infos.getDynamicPDOs(): + if PdoConfig and PdoAssign: dynamic_pdos = {} dynamic_pdos_number = 0 for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), @@ -1104,11 +1114,11 @@ if pdo["entries_number"] == 255: dynamic_pdos[pdo_type]["pdos"].pop(0) - + pdo_offset = 0 entry_offset = 0 for sync_manager_infos in sync_managers: - + for pdo_infos in sync_manager_infos["pdos"]: pdo_infos["offset"] = entry_offset pdo_entries = pdo_infos["entries"] @@ -1130,7 +1140,13 @@ pdos_infos[element] = "\n".join(pdos_infos[element]) str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos - + + for (index, subindex), entry_declaration in slave_variables.iteritems(): + if not entry_declaration["mapped"]: + message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \ + (index, subindex, type_infos["device_type"]) + self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n") + for element in ["used_pdo_entry_offset_variables_declaration", "used_pdo_entry_configuration", "located_variables_declaration", @@ -1216,17 +1232,12 @@ setattr(cls, "ExtractDataTypes", ExtractDataTypes) - def getInitCmd(self): + def getCoE(self): mailbox = self.getMailbox() - if mailbox is None: - return [] - - coe = mailbox.getCoE() - if coe is None: - return [] - - return coe.getInitCmd() - setattr(cls, "getInitCmd", getInitCmd) + if mailbox is not None: + return mailbox.getCoE() + return None + setattr(cls, "getCoE", getCoE) def GetEntriesList(self): if self.DataTypes is None: diff -r 7d0ebbff1d08 -r 49242019a9ca etherlab/plc_cia402node.c --- a/etherlab/plc_cia402node.c Sat Sep 22 12:07:06 2012 +0200 +++ b/etherlab/plc_cia402node.c Sun Sep 23 23:25:57 2012 +0200 @@ -48,7 +48,8 @@ %(init_entry_variables)s *__IW%(location)s_0 = __MK_Alloc_AXIS_REF(); __CIA402Node_%(location)s.axis = __MK_GetPublic_AXIS_REF(*__IW%(location)s_0); - return 0; + *(__CIA402Node_%(location)s.ModesOfOperation) = 0x08; + return 0; } void __cleanup_%(location)s() diff -r 7d0ebbff1d08 -r 49242019a9ca etherlab/plc_etherlab.c --- a/etherlab/plc_etherlab.c Sat Sep 22 12:07:06 2012 +0200 +++ b/etherlab/plc_etherlab.c Sun Sep 23 23:25:57 2012 +0200 @@ -21,9 +21,6 @@ // declaration of interface variables %(located_variables_declaration)s -// Optional features -#define CONFIGURE_PDOS %(configure_pdos)d - // process data uint8_t *domain1_pd = NULL; %(used_pdo_entry_offset_variables_declaration)s @@ -34,9 +31,7 @@ }; /*****************************************************************************/ -#if CONFIGURE_PDOS %(pdos_configuration_declaration)s -#endif int rt_fd = -1; CstructMstrAttach MstrAttach; @@ -64,10 +59,8 @@ domain1 = ecrt_master_create_domain(master); if (!domain1) return -1; -#if CONFIGURE_PDOS - fprintf(stdout, "Configure PDOs...\n"); - %(slaves_configuration)s -#endif + // slaves PDO configuration +%(slaves_configuration)s if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) { fprintf(stderr, "PDO entry registration failed!\n"); @@ -76,8 +69,10 @@ ecrt_master_set_send_interval(master, common_ticktime__); + // slaves initialization %(slaves_initialization)s + // extracting default value for not mapped entry in output PDOs %(slaves_output_pdos_default_values_extraction)s sprintf(&rt_dev_file[0],"%%s%%u",EC_RTDM_DEV_FILE_NAME,0);