canfestival/config_utils.py
changeset 1740 b789b695b5c6
parent 1739 ec153828ded2
child 1741 dd94b9a68c61
equal deleted inserted replaced
1739:ec153828ded2 1740:b789b695b5c6
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
    24 
    25 from types import *
    25 from types import *
    26 
    26 
    27 # Translation between IEC types and Can Open types
    27 # Translation between IEC types and Can Open types
    28 IECToCOType = {"BOOL":0x01, "SINT":0x02, "INT":0x03,"DINT":0x04,"LINT":0x10,
    28 IECToCOType = {
    29                "USINT":0x05,"UINT":0x06,"UDINT":0x07,"ULINT":0x1B,"REAL":0x08,
    29     "BOOL":    0x01,
    30                "LREAL":0x11,"STRING":0x09,"BYTE":0x05,"WORD":0x06,"DWORD":0x07,
    30     "SINT":    0x02,
    31                "LWORD":0x1B,"WSTRING":0x0B}
    31     "INT":     0x03,
       
    32     "DINT":    0x04,
       
    33     "LINT":    0x10,
       
    34     "USINT":   0x05,
       
    35     "UINT":    0x06,
       
    36     "UDINT":   0x07,
       
    37     "ULINT":   0x1B,
       
    38     "REAL":    0x08,
       
    39     "LREAL":   0x11,
       
    40     "STRING":  0x09,
       
    41     "BYTE":    0x05,
       
    42     "WORD":    0x06,
       
    43     "DWORD":   0x07,
       
    44     "LWORD":   0x1B,
       
    45     "WSTRING": 0x0B
       
    46 }
    32 
    47 
    33 # Constants for PDO types
    48 # Constants for PDO types
    34 RPDO = 1
    49 RPDO = 1
    35 TPDO = 2
    50 TPDO = 2
    36 
    51 
    40 PDOTypeBaseCobId = {RPDO: 0x200, TPDO: 0x180}
    55 PDOTypeBaseCobId = {RPDO: 0x200, TPDO: 0x180}
    41 
    56 
    42 VariableIncrement = 0x100
    57 VariableIncrement = 0x100
    43 VariableStartIndex = {TPDO: 0x2000, RPDO: 0x4000}
    58 VariableStartIndex = {TPDO: 0x2000, RPDO: 0x4000}
    44 VariableDirText = {TPDO: "__I", RPDO: "__Q"}
    59 VariableDirText = {TPDO: "__I", RPDO: "__Q"}
    45 VariableTypeOffset = dict(zip(["","X","B","W","D","L"], range(6)))
    60 VariableTypeOffset = dict(zip(["", "X", "B", "W", "D", "L"], range(6)))
    46 
    61 
    47 TrashVariables = [(1, 0x01), (8, 0x05), (16, 0x06), (32, 0x07), (64, 0x1B)]
    62 TrashVariables = [(1, 0x01), (8, 0x05), (16, 0x06), (32, 0x07), (64, 0x1B)]
    48 
    63 
    49 #-------------------------------------------------------------------------------
    64 #-------------------------------------------------------------------------------
    50 #                  Specific exception for PDO mapping errors
    65 #                  Specific exception for PDO mapping errors
   220             node.SetNodeID(nodeid)
   235             node.SetNodeID(nodeid)
   221 
   236 
   222             RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node)
   237             RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node)
   223 
   238 
   224             # Get Slave's default SDO server parameters
   239             # Get Slave's default SDO server parameters
   225             RSDO_cobid = node.GetEntry(0x1200,0x01)
   240             RSDO_cobid = node.GetEntry(0x1200, 0x01)
   226             if not RSDO_cobid:
   241             if not RSDO_cobid:
   227                 RSDO_cobid = 0x600 + nodeid
   242                 RSDO_cobid = 0x600 + nodeid
   228             TSDO_cobid = node.GetEntry(0x1200,0x02)
   243             TSDO_cobid = node.GetEntry(0x1200, 0x02)
   229             if not TSDO_cobid:
   244             if not TSDO_cobid:
   230                 TSDO_cobid = 0x580 + nodeid
   245                 TSDO_cobid = 0x580 + nodeid
   231 
   246 
   232             # Configure Master's SDO parameters entries
   247             # Configure Master's SDO parameters entries
   233             self.Manager.ManageEntriesOfCurrent([0x1280 + idx], [], self.MasterNode)
   248             self.Manager.ManageEntriesOfCurrent([0x1280 + idx], [], self.MasterNode)
   382                     if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype:
   397                     if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype:
   383                         raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3}  for location \"{a4}\"").\
   398                         raise PDOmappingException, _("Invalid type \"{a1}\"-> {a2} != {a3}  for location \"{a4}\"").\
   384                             format(a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"], a4 = name)
   399                             format(a1 = location["IEC_TYPE"], a2 = COlocationtype, a3 = subentry_infos["type"], a4 = name)
   385 
   400 
   386                     typeinfos = node.GetEntryInfos(COlocationtype)
   401                     typeinfos = node.GetEntryInfos(COlocationtype)
   387                     self.IECLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction],
   402                     self.IECLocations[name] = {
   388                                                 "nodeid": nodeid, "index": index,"subindex": subindex,
   403                         "type":         COlocationtype,
   389                                                 "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation}
   404                         "pdotype":      SlavePDOType[direction],
       
   405                         "nodeid":       nodeid,
       
   406                         "index":        index,
       
   407                         "subindex":     subindex,
       
   408                         "bit":          numbit,
       
   409                         "size":         typeinfos["size"],
       
   410                         "sizelocation": sizelocation
       
   411                     }
   390                 else:
   412                 else:
   391                     raise PDOmappingException, _("Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))").\
   413                     raise PDOmappingException, _("Not PDO mappable variable : '{a1}' (ID:{a2},Idx:{a3},sIdx:{a4}))").\
   392                         format(a1 = name, a2 = nodeid, a3 = "%x" % index, a4 = "%x" % subindex)
   414                         format(a1 = name, a2 = nodeid, a3 = "%x" % index, a4 = "%x" % subindex)
   393 
   415 
   394         #-------------------------------------------------------------------------------
   416         #-------------------------------------------------------------------------------
   548                                      variable_infos["nodeid"]
   570                                      variable_infos["nodeid"]
   549 
   571 
   550                     # Generate entry name
   572                     # Generate entry name
   551                     indexname = "%s%s%s_%d" % (VariableDirText[variable_infos["pdotype"]],
   573                     indexname = "%s%s%s_%d" % (VariableDirText[variable_infos["pdotype"]],
   552                                                  variable_infos["sizelocation"],
   574                                                  variable_infos["sizelocation"],
   553                                                  '_'.join(map(str,current_location)),
   575                                                  '_'.join(map(str, current_location)),
   554                                                  variable_infos["nodeid"])
   576                                                  variable_infos["nodeid"])
   555 
   577 
   556                     # Search for an entry that has an empty subindex
   578                     # Search for an entry that has an empty subindex
   557                     while mapvariableidx < VariableStartIndex[variable_infos["pdotype"]] + 0x2000:
   579                     while mapvariableidx < VariableStartIndex[variable_infos["pdotype"]] + 0x2000:
   558                         # Entry doesn't exist
   580                         # Entry doesn't exist
   609     @return: a modified copy of the given CanFestival network editor model
   631     @return: a modified copy of the given CanFestival network editor model
   610     """
   632     """
   611 
   633 
   612     dcfgenerator = ConciseDCFGenerator(nodelist, nodename)
   634     dcfgenerator = ConciseDCFGenerator(nodelist, nodename)
   613     dcfgenerator.GenerateDCF(locations, current_location, sync_TPDOs)
   635     dcfgenerator.GenerateDCF(locations, current_location, sync_TPDOs)
   614     masternode,pointers = dcfgenerator.GetMasterNode(), dcfgenerator.GetPointedVariables()
   636     masternode, pointers = dcfgenerator.GetMasterNode(), dcfgenerator.GetPointedVariables()
   615     # allow access to local OD from Master PLC
   637     # allow access to local OD from Master PLC
   616     pointers.update(LocalODPointers(locations, current_location, masternode))
   638     pointers.update(LocalODPointers(locations, current_location, masternode))
   617     return masternode,pointers
   639     return masternode, pointers
   618 
   640 
   619 
   641 
   620 def LocalODPointers(locations, current_location, slave):
   642 def LocalODPointers(locations, current_location, slave):
   621     IECLocations = {}
   643     IECLocations = {}
   622     pointers = {}
   644     pointers = {}
   677     # Boolean that indicate if reference result must be redefined
   699     # Boolean that indicate if reference result must be redefined
   678     reset = False
   700     reset = False
   679 
   701 
   680     # Extract command options
   702     # Extract command options
   681     try:
   703     try:
   682         opts, args = getopt.getopt(sys.argv[1:], "hr", ["help","reset"])
   704         opts, args = getopt.getopt(sys.argv[1:], "hr", ["help", "reset"])
   683     except getopt.GetoptError:
   705     except getopt.GetoptError:
   684         # print help information and exit:
   706         # print help information and exit:
   685         usage()
   707         usage()
   686         sys.exit(2)
   708         sys.exit(2)
   687 
   709 
   707     manager = NodeManager()
   729     manager = NodeManager()
   708     nodelist = NodeList(manager)
   730     nodelist = NodeList(manager)
   709     result = nodelist.LoadProject("test_config")
   731     result = nodelist.LoadProject("test_config")
   710 
   732 
   711     # List of locations, we try to map for test
   733     # List of locations, we try to map for test
   712     locations = [{"IEC_TYPE":"BYTE","NAME":"__IB0_1_64_24576_1","DIR":"I","SIZE":"B","LOC":(0,1,64,24576,1)},
   734     locations = [
   713                  {"IEC_TYPE":"INT","NAME":"__IW0_1_64_25601_2","DIR":"I","SIZE":"W","LOC":(0,1,64,25601,2)},
   735         {"IEC_TYPE": "BYTE",  "NAME": "__IB0_1_64_24576_1", "DIR": "I", "SIZE": "B", "LOC": (0, 1, 64, 24576, 1)},
   714                  {"IEC_TYPE":"INT","NAME":"__IW0_1_64_25601_3","DIR":"I","SIZE":"W","LOC":(0,1,64,25601,3)},
   736         {"IEC_TYPE": "INT",   "NAME": "__IW0_1_64_25601_2", "DIR": "I", "SIZE": "W", "LOC": (0, 1, 64, 25601, 2)},
   715                  {"IEC_TYPE":"INT","NAME":"__QW0_1_64_25617_2","DIR":"Q","SIZE":"W","LOC":(0,1,64,25617,1)},
   737         {"IEC_TYPE": "INT",   "NAME": "__IW0_1_64_25601_3", "DIR": "I", "SIZE": "W", "LOC": (0, 1, 64, 25601, 3)},
   716                  {"IEC_TYPE":"BYTE","NAME":"__IB0_1_64_24578_1","DIR":"I","SIZE":"B","LOC":(0,1,64,24578,1)},
   738         {"IEC_TYPE": "INT",   "NAME": "__QW0_1_64_25617_2", "DIR": "Q", "SIZE": "W", "LOC": (0, 1, 64, 25617, 1)},
   717                  {"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_1","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,1)},
   739         {"IEC_TYPE": "BYTE",  "NAME": "__IB0_1_64_24578_1", "DIR": "I", "SIZE": "B", "LOC": (0, 1, 64, 24578, 1)},
   718                  {"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_2","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,2)},
   740         {"IEC_TYPE": "UDINT", "NAME": "__ID0_1_64_25638_1", "DIR": "I", "SIZE": "D", "LOC": (0, 1, 64, 25638, 1)},
   719                  {"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_3","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,3)},
   741         {"IEC_TYPE": "UDINT", "NAME": "__ID0_1_64_25638_2", "DIR": "I", "SIZE": "D", "LOC": (0, 1, 64, 25638, 2)},
   720                  {"IEC_TYPE":"UDINT","NAME":"__ID0_1_64_25638_4","DIR":"I","SIZE":"D","LOC":(0,1,64,25638,4)},
   742         {"IEC_TYPE": "UDINT", "NAME": "__ID0_1_64_25638_3", "DIR": "I", "SIZE": "D", "LOC": (0, 1, 64, 25638, 3)},
   721                  {"IEC_TYPE":"UDINT","NAME":"__ID0_1_4096_0","DIR":"I","SIZE":"D","LOC":(0,1,4096,0)}]
   743         {"IEC_TYPE": "UDINT", "NAME": "__ID0_1_64_25638_4", "DIR": "I", "SIZE": "D", "LOC": (0, 1, 64, 25638, 4)},
       
   744         {"IEC_TYPE": "UDINT", "NAME": "__ID0_1_4096_0",     "DIR": "I", "SIZE": "D", "LOC": (0, 1, 4096, 0)}
       
   745     ]
   722 
   746 
   723     # Generate MasterNode configuration
   747     # Generate MasterNode configuration
   724     try:
   748     try:
   725         masternode, pointedvariables = GenerateConciseDCF(locations, (0, 1), nodelist, True, "TestNode")
   749         masternode, pointedvariables = GenerateConciseDCF(locations, (0, 1), nodelist, True, "TestNode")
   726     except ValueError, message:
   750     except ValueError, message: